Vue3 中ref 和 reactive区别
Vue3 响应式数据的区别
ref 和 reactive 总结
- ref 和 reactive 都是用来创建响应式数据的
| 特性 | ref | reactive |
|---|---|---|
| 适用类型 | 任何类型 (基本类型、对象、数组) | 仅对象类型 (对象、数组、Map, Set等) |
| 访问/修改方式 | JavaScript 中需 .value,模板中自动解包 | 直接通过 . 或 [] 操作,无需 .value |
| 替换整个值 | ref.value = newValue (保持响应性) | obj = newValue (会丢失响应性) |
| 解构 | 解构 ref 本身仍保持响应性 | 解构属性会丢失响应性 |
| 内部实现 | 返回一个带有 .value 属性的 Ref 对象 | 返回一个 Proxy 代理的原始对象 |
ref
- 作用 :创建一个引用,可以用来包装任何类型的值(基本数据类型如 string, number, boolean,也可以是对象或数组)。
- 访问和修改:
- 使用 ref 创建的响应式变量,需要通过其 .value 属性来访问或修改其内部的值。
- 在 JavaScript/TypeScript 中:必须使用 .value。
- 在 模板 (template) 中:Vue 会自动解包 (unwrap),所以不需要写 .value。
import { ref } from 'vue'
// 创建一个响应式的数字
const count = ref(0)
console.log(count.value) // 访问值:0
count.value = 1 // 修改值
// 创建一个响应式的对象
const user = ref({ name: 'Alice', age: 25 })
user.value.age = 26 // 必须通过 .value 访问对象
// 在模板中使用
// <template>
// <div>{{ count }}</div> <!-- 直接写 count,不用 .value -->
// <div>{{ user.name }}</div> <!-- 直接解包,可以像普通对象一样访问 -->
// </template>reactive
- 作用 :创建一个响应式对象。它只能用于对象类型(包括普通对象、数组、Map、Set 等)。
- 访问和修改:
- 直接像操作普通对象一样,通过 . 或 [] 来访问和修改属性。不需要 .value
- 限制:
- 不能用于基本数据类型。
- 替换整个对象会丢失响应性:如果你直接给一个 reactive 变量赋一个新对象,那么新对象将不再是响应式的,因为它创建了一个全新的引用。
- 替换整个对象会丢失响应性:如果你直接给一个 reactive 变量赋一个新对象,那么新对象将不再是响应式的,因为它创建了一个全新的引用。
import { reactive } from 'vue'
// 创建一个响应式对象
const state = reactive({
count: 0,
user: {
name: 'Bob',
age: 30
}
})
console.log(state.count) // 访问:0
state.count = 1 // 修改:直接赋值
// ❌ 错误:直接替换整个对象会丢失响应性
// state = { count: 10, user: { name: 'Charlie', age: 35 } }
// ✅ 正确:应该修改对象的属性
state.count = 10
state.user.name = 'Charlie'
// ❌ 错误:解构会丢失响应性
// const { count } = state
// count++ // 这不会触发视图更新
// ✅ 正确:保持响应性,可以使用 toRefs (见下文)
----------------------------------------------------------------
import { reactive, toRefs } from 'vue'
const state = reactive({
count: 0,
name: 'Alice'
})
// 将 reactive 对象的每个属性转换为 ref
const { count, name } = toRefs(state)
// 现在 count 和 name 都是 ref,具有响应性
count.value++ // 这会触发更新
- reactive 解构后丢失响应性的问题,可以使用 toRefs。它会将 reactive 对象的所有属性都转换为 ref
二者的使用场景
- 首选 ref:对于大多数情况,尤其是当你不确定类型,或者需要处理基本数据类型时,ref 更加灵活和安全。现代 IDE 的自动补全也能很好地处理 .value。
- 使用 reactive:当你有一个复杂且固定结构的对象,并且你希望代码看起来更简洁(不需要 .value),可以考虑使用 reactive。但要特别注意不要直接替换整个对象或进行解构。
版权所有
版权归属:念宇
