在Vue3的响应式系统中,ref
、reactive
、toRef
、toRefs
是核心API,它们在使用场景和特性上有显著区别。以下是它们的详细对比:
.value
访问或修改值。ref
包装后变为响应式。reactive
处理,深层嵌套属性也会响应。.value
(顶层属性)。const count = ref(0);
count.value++; // 修改值
const obj = ref({ a: 1 });
obj.value.a = 2; // 响应式更新
toRefs
。const state = reactive({ count: 0 });
state.count++; // 直接修改
reactive
生成)的某个属性转换为独立的ref
,保持响应式连接。ref
传递,且保持与原对象的响应关联。const state = reactive({ foo: 1 });
const fooRef = toRef(state, 'foo');
fooRef.value++; // 修改会同步到state.foo
ref
,用于解构/展开时保持响应性。const state = reactive({ count: 0 });
const stateRefs = toRefs(state); // { count: Ref<number> }
const { count } = stateRefs; // 解构后仍为响应式
特性 | ref | reactive | toRef | toRefs |
---|---|---|---|---|
适用类型 | 基本类型、对象/数组 | 对象/数组 | 响应式对象的属性 | 响应式对象 |
返回值 | Ref对象(通过.value 访问) |
Proxy代理对象 | Ref对象 | 普通对象(属性为Ref) |
响应式保持 | 直接创建响应式 | 直接创建响应式 | 依赖原响应式对象的属性 | 依赖原响应式对象 |
解构响应性 | 支持(需用.value ) |
直接解构会丢失 | 保持响应式 | 保持响应式 |
模板使用 | 自动解包(无需.value ) |
直接访问属性 | 自动解包 | 自动解包 |
ref
。reactive
;若需解构或组合式函数返回,用toRefs
。toRef
。ref
传递时,用toRef
(避免用ref
导致断开连接)。错误解构响应式对象:
const state = reactive({ count: 0 });
const { count } = state; // 非响应式!
正确解构:
const state = reactive({ count: 0 });
const { count } = toRefs(state); // count是Ref
保持属性响应式:
const state = reactive({ x: 1 });
const xRef = toRef(state, 'x'); // 修改xRef.value会更新state.x
通过合理选择API,可以更高效地管理Vue3的响应式数据。