文章 文章 posts

Vue 3 响应式 API 深入解析:reactive、ref、toRef、toRefs

Vue 3 提供了丰富的响应式 API,让状态管理更加灵活。本文介绍四个核心 API:reactive、ref、toRef、toRefs,重点分析 区别、使用场景,并给出常见错误示例。

1️⃣ reactive

  • 作用:将对象或数组转换为响应式对象(深层响应式)。
  • 适用场景:
    • 对象或数组需要整体响应式
    • 包含嵌套对象或数组,修改内部属性也希望触发更新
  • 特点:
    • 返回一个 Proxy
    • 深层响应式
    • 不适合基本类型(number、string、boolean)

正确示例:

js
import { reactive } from 'vue'

const state = reactive({
  count: 0,
  info: { name: 'Alice' }
})

state.count++           // 响应式更新
state.info.name = 'Bob' // 深层响应式

`

错误示例(对基本类型无效):

js
const count = reactive(0) // ❌ 不会成为响应式

2️⃣ ref

  • 作用:为基本类型或对象创建响应式引用

  • 适用场景:

    • 基本类型(number、string、boolean)
    • 对象也可用 ref 包裹,但内部对象不是深层响应式(除非用 reactive 包裹)
  • 访问/修改:通过 .value

正确示例:

js
import { ref, reactive } from 'vue'

const count = ref(0)
count.value++       // 响应式更新

const obj = ref({ name: 'Alice' })
obj.value.name = 'Bob'  // 对象内部也可修改

错误示例(解构后失去响应式):

js
const obj = ref({ name: 'Alice' })
const { name } = obj.value
name = 'Bob'          // ❌ 不会触发响应式更新

3️⃣ toRef

  • 作用:将响应式对象的单个属性转换为 ref

  • 适用场景:

    • 需要单独解构对象的某个属性,同时保持响应式
  • 特点:

    • 修改 ref.value 会同步到原对象
    • 避免响应式丢失问题

正确示例:

js
import { reactive, toRef } from 'vue'

const state = reactive({ count: 0 })
const countRef = toRef(state, 'count')

countRef.value++       // state.count 同步更新

错误示例(直接解构属性):

js
const { count } = state   // ❌ count 不是 ref,解构后丢失响应式
count++                   // 不会更新 state.count

4️⃣ toRefs

  • 作用:将响应式对象的所有属性都转换为 ref,返回对象

  • 适用场景:

    • 解构对象后仍希望保持响应式
  • 特点:

    • 每个属性变成 ref
    • 修改 ref.value 会同步到原对象

正确示例:

js
import { reactive, toRefs } from 'vue'

const state = reactive({ count: 0, name: 'Alice' })
const { count, name } = toRefs(state)

count.value++        // state.count 同步更新
name.value = 'Bob'   // state.name 同步更新

错误示例(解构 reactive 对象直接赋值):

js
const { count, name } = state   // ❌ 不使用 toRefs
count++                         // 不会触发响应式

5️⃣ 区别与总结

API 适用类型 响应式深度 解构安全 使用场景
reactive 对象/数组 深层 ❌ 整体对象响应式,嵌套属性响应
ref 基本类型/对象 单层 ❌ 单值响应式,基本类型或对象引用
toRef 对象单个属性 单层 ✅ 解构单个属性仍保持响应式
toRefs 对象所有属性 单层 ✅ 解构对象后仍保持所有属性响应式

✅ 小结

  1. reactive:对象/数组整体响应式
  2. ref:基本类型或单个对象引用
  3. toRef:单个属性解构安全
  4. toRefs:多个属性解构安全
提示

对象解构后要保持响应式,必须使用 toRef 或 toRefs。
基本类型一定要用 ref,不能直接用 reactive。
使用不当(解构 reactive 或 ref.value 内部对象)会丢失响应式。