文章目录
- ref 和 reactive
- 一、差异
- 二、能否替代的场景分析
- (1)基本类型数据
- (2)对象类型数据
- (3)数组类型数据
- (4) 需要整体替换的场景
- 三、替代方案与兼容写法
- 1. 用 reactive 模拟 ref
- 2. 用 ref 模拟 reactive
- 四、最佳实践建议
- 五、性能对比
- 六 结论:
ref 和 reactive
一、差异

| 特性 | ref | reactive |
|---|---|---|
| 适用类型 | 任意类型(包括基本类型) | 仅对象/数组 |
| 访问对象 | 需要通过 .value | 直接访问属性 |
| 整体替换 | ✅支持(直接赋值) | ❌不支持(需要特殊处理) |
| 解构保持相应性 | ❌需要配合 toRef | ❌需要配合 toRef |
| 性能开销 | 较低(仅包装一层) | 较高(深度代理) |
二、能否替代的场景分析
(1)基本类型数据
// ✅ 必须用 ref
const count = ref(0); // 正确
const count = reactive(0); // ❌ 错误(reactive 只能处理对象)
(2)对象类型数据
// ✅ 可以用 reactive 替代 ref
const objRef = ref({ a: 1 });
const objReactive = reactive({ a: 1 });// 访问方式差异
console.log(objRef.value.a); // ref 需要 .value
console.log(objReactive.a); // reactive 直接访问
(3)数组类型数据
// ✅ 可以用 reactive 替代 ref
const arrRef = ref([1, 2, 3]);
const arrReactive = reactive([1, 2, 3]);// 修改操作差异
arrRef.value.push(4); // ref 需要 .value
arrReactive.push(4); // reactive 直接操作
(4) 需要整体替换的场景
// ✅ 必须用 ref
const state = ref({ a: 1 });
state.value = { a: 2 }; // ✅ 正确// ❌ reactive 无法直接替换
const state = reactive({ a: 1 });
state = { a: 2 }; // ❌ 错误(失去响应性)
三、替代方案与兼容写法
1. 用 reactive 模拟 ref
// 通过 reactive 包装单属性对象
const count = reactive({ value: 0 });
console.log(count.value); // 访问方式与 ref 一致
2. 用 ref 模拟 reactive
// 通过 ref 包装对象
const obj = ref({ a: 1 });
console.log(obj.value.a); // 访问时需要 .value
四、最佳实践建议
- 基本类型 → 必须用 ref
- 对象/数组 → 优先用 reactive(除非需要整体替换)
- 复杂数据结构 → 混合使用:
const state = reactive({count: ref(0), // 嵌套 refuser: reactive({ // 嵌套 reactivename: 'Alice'})
});
- 模板中使用 → 优先用 reactive(避免频繁 .value)
五、性能对比
| 操作 | ref | reactive |
|---|---|---|
| 创建响应式对象 | ⭐快 | ⭐⭐慢 |
| 属性访问 | ⭐⭐⭐快 | ⭐⭐快 |
| 数组修改 | ⭐⭐中 | ⭐⭐⭐快 |
| 整体替换 | ⭐⭐⭐快 | ❌不支持 |
六 结论:
不能简单用 reactive 完全替代 ref,但可以根据数据类型和使用场景选择:
- 基本类型 → 必须用 ref
- 对象/数组 → 优先用 reactive
- 需要整体替换 → 必须用 ref
- 模板中直接访问 → 优先用 reactive(减少 .value 噪音)