题目
Vue 3 Composition API 中 ref 和 reactive 的区别与使用场景
信息
- 类型:问答
- 难度:⭐
考点
响应式基础,ref 使用,reactive 使用,数据类型选择
快速回答
在 Vue 3 Composition API 中:
- ref 用于创建基本类型(如字符串、数字)或对象/数组的响应式引用,通过
.value访问值 - reactive 仅用于创建对象(包括数组)的深层响应式代理,直接访问属性
- 推荐:基本类型用
ref,对象/数组根据需求选择(简单对象用reactive,复杂场景可用ref)
1. 核心区别
ref 和 reactive 都是创建响应式数据的函数,主要区别在于:
- 数据类型:
ref适用于任何类型,reactive仅适用于对象/数组 - 访问方式:
ref需要通过.value访问值,reactive直接访问属性 - 实现原理:
ref内部使用reactive包装对象,基本类型通过 getter/setter 实现响应
2. 代码示例
// ref 示例(基本类型 + 对象)
import { ref } from 'vue';
const count = ref(0); // 基本类型
const user = ref({ name: 'Alice' }); // 对象
// 访问/修改
console.log(count.value); // 0
count.value++; // 修改
user.value.name = 'Bob'; // 通过 .value 访问对象
// reactive 示例(对象)
import { reactive } from 'vue';
const state = reactive({
name: 'Alice',
age: 30,
hobbies: ['reading', 'coding']
});
// 直接访问属性
state.age = 31;
state.hobbies.push('swimming');3. 最佳实践
- 基本类型:必须使用
ref(reactive无法直接代理基本类型) - 简单对象:推荐
reactive(避免频繁使用.value) - 复杂场景:
- 需要解构时:用
ref+toRefs(reactive直接解构会失去响应性) - 需要替换整个对象:用
ref(reactive无法直接替换根对象)
- 需要解构时:用
4. 常见错误
- 错误 1:直接解构
reactive对象// ❌ 错误示例 const { name, age } = state; // 解构后失去响应性 // ✅ 正确做法 const { name, age } = toRefs(state); // 保持响应性 - 错误 2:忘记
ref的.value// ❌ 错误示例 console.log(count); // 输出 Ref 对象而非实际值 // ✅ 正确做法 console.log(count.value); - 错误 3:用
reactive包裹基本类型// ❌ 无效操作(不会报错但无响应性) const num = reactive(10); // 实际返回原始值 10 // ✅ 正确做法 const num = ref(10);
5. 原理说明
- ref:创建一个包含
value属性的响应式引用对象。基本类型通过Object.defineProperty实现响应,对象类型内部转为reactive代理 - reactive:使用 ES6 Proxy 深度代理整个对象,递归转换嵌套属性
6. 扩展知识
- toRefs:将
reactive对象转换为普通对象,每个属性都是ref,用于解构保持响应性 - shallowRef/shallowReactive:创建非深度响应数据(
shallowRef不自动解包嵌套ref,shallowReactive只代理第一层属性) - 组合式函数返回时推荐统一使用
ref(保持一致性)