Vue3中,ref 是一个用于创建响应式数据的函数,它返回一个具有 .value 属性的对象 ref 适用于基本类型和对象,访问和修改时需要使用 .value 在模板中,Vue 会自动解包 ref,无需 .value 如果处理的是对象,reactive 可能更方便(但 ref 更通用) 如果你需要更复杂的响应式数据管理,可以考虑 reactive 或 computed import { ref } from 'vue'; // 创建一个响应式变量 const count = ref(0); // 访问值需要使用 .value console.log(count.value); // 0 // 修改值 count.value = 10; console.log(count.value); // 10 在模板中,Vue 会自动解包 ref,不需要写 .valueref 与 reactive 的区别 特性 ref reactive 数据类型 适用于基本类型(number, string, boolean和对象 仅适用于对象 访问方式 需要 .value 直接访问属性 解包 在模板中自动解包 不需要解包 ref 也可以用于对象,但访问和修改时仍需 .value const user = ref({ name: 'Alice', age: 25 }); console.log(user.value.name); // 'Alice' user.value.age = 26; {{ count }}
ref 在组合式 API 中的常见用途 定义响应式变量 const isLoading = ref(false); 结合 watch 监听变化 watch(count, (newVal) => { console.log('count changed:', newVal); }); 在 setup() 中返回供模板使用 setup() { const message = ref('Hello Vue 3'); return { message }; }
Vue3 的 ref 需要 .value 确实让一些开发者觉得有点烦,尤其是从 Vue 2 的 data 或 reactive 转过来的开发者。 为什么 Vue 3 的 ref 需要 .value? 区分响应式和非响应式变量 ref 适用于基本类型(string、number、boolean),而 reactive 适用于对象。 由于 JavaScript 基本类型是按值传递,ref 必须用 .value 来访问内部值,否则无法追踪变化。 reactive 不需要 .value,因为它直接代理整个对象。 保持一致性 在组合式 API 中,ref 可以用于任何数据类型(基本类型、对象、数组),而 reactive 仅适用于对象。 使用 .value 可以统一访问方式,避免混淆。 模板自动解包 模版里 Vue 会自动解包 ref,不需要写 .value
如何减少 .value 的麻烦? 1. 使用 reactive 代替 ref(适用于对象) import { reactive } from 'vue'; const user = reactive({ name: 'Alice', age: 25 }); console.log(user.name); // 不需要 .value 适用场景:管理复杂对象或状态时更简洁 缺点:不能用于基本类型(如 string、number) 2. 使用解构 + toRefs(让 reactive 的属性变成 ref) import { reactive, toRefs } from 'vue'; const state = reactive({ count: 0, name: 'Vue' }); const { count, name } = toRefs(state); // 解构后仍然是 ref console.log(count.value); // 0(仍然需要 .value) 适用场景:在组合式函数中返回多个 ref 时更方便 3. 使用 unref 简化 .value 判断 import { ref, unref } from 'vue'; const count = ref(0); console.log(unref(count)); // 0(如果是 ref 返回 .value,否则返回本身) 适用场景:在工具函数里处理可能是 ref 或普通值的变量。 4. 使用 computed 自动解包 import { ref, computed } from 'vue'; const count = ref(0); const double = computed(() => count.value * 2); // 自动追踪依赖 console.log(double.value); // 仍然需要 .value 适用场景:计算属性依赖 ref 时仍然需要 .value,但在模板里会自动解包。 5. 使用 watch 时自动解包 import { ref, watch } from 'vue'; const count = ref(0); watch(count, (newVal) => { console.log(newVal); // 自动解包,不需要 .value }); 适用场景:watch 会自动解包 ref,减少 .value 的使用
什么时候必须用 ref 而不是 reactive? 基本类型(string/number/boolean) reactive 不能直接用于基本类型,必须用 ref。 const age = ref(25); // 必须用 ref const user = reactive({ age: 25 }); // 可以用 reactive 包装 在组合式函数中返回响应式变量 ref 更适合在 setup() 或 Composable 函数中返回,因为 reactive 会失去响应性: function useCounter() { const count = ref(0); return { count }; // 仍然保持响应式 }