Ref 和 Reactive 的本质区别?为什么 Vue 3 要搞出两个定义数据的 API?
我们用**“追踪器”和“盒子”**的例子重来一遍。
Vue 的核心任务就是:你要是改了数据,Vue 得立马知道(以便更新网页)。
1. 为什么 ref 需要 .value?
想象你要追踪一个数字 0。
在 JS 的世界里,数字就像一枚硬币。
- 你没法在硬币上装“GPS追踪器”。硬币太小了,也是死物,没地方贴。
Vue 怎么做?
Vue 给你发了一个盒子(这就是 ref)。
它把硬币(0)放进了盒子里,然后在盒子上装了警报器。
- 当你拿变量时: 你拿到的不是硬币,而是整个盒子。
- 当你要改值时: 你必须打开盒子,这就叫
.value。count是盒子。count.value是“打开盒子拿硬币”这个动作。
结论: 因为硬币(数字、字符串)本身装不了监控,只能装在盒子上。所以你每次必须**“打开盒子”(.value)** 才能摸到数据。
2. 为什么 reactive 不需要 .value?
想象你要追踪一个背包(里面有很多东西)。
在 JS 的世界里,对象(Object)就像这个背包。
- 背包很大,Vue 有能力直接把“GPS追踪器”缝在背包的拉链上。
Vue 怎么做?
Vue 给了你一个被改装过的背包(这就是 reactive)。
- 当你拿变量时: 你直接拿到了这个带监控的背包。
- 当你要改值时: 你直接拉开拉链拿东西就行了(比如
backpack.name)。 - 不需要 .value: 因为监控就在背包皮上,你只要动背包,Vue 就知道。不需要再往外面套个盒子了。
3. 为什么 reactive 容易出问题(解构丢失响应性)?
这是最关键的。
如果你用 reactive 创建了一个智能背包 state,里面放了一个苹果 count。
const state = reactive({ count: 0 }); // state 是智能背包
如果你写了这行代码:
let { count } = state; // 从背包里把苹果拿出来,揣自己兜里
这时候发生了什么?
你把苹果(count)从智能背包里掏出来了,放在了普通的桌子上。
- 智能背包(
state)有监控。 - 但是这个苹果(
count)只是一个普通的苹果,它身上没有监控!
所以,当你修改桌子上的这个苹果时,Vue 完全不知道,网页也不会变。这就是所谓的“失去响应性”。
而 ref(盒子)就不怕这个问题,因为你不管把盒子拎到哪里,盒子上的警报器始终都在。
终极简化总结
-
Ref (盒子):
- 针对: 简单的值(数字、字符串)。
- 样子:
const a = ref(0)。 - 操作: 必须用
a.value(打开盒子)才能改。 - 优点: 盒子随便拎,走到哪都有监控,最稳。
-
Reactive (智能背包):
- 针对: 复杂的对象(一堆数据)。
- 样子:
const b = reactive({ x: 1 })。 - 操作: 直接
b.x(拉拉链)就能改,不需要.value。 - 缺点: 里面的东西不能掏出来单独用,掏出来就没监控了。
场景,推荐使用,理由
“基础类型 (boolean, string, number)”,ref,const showModal = ref(false) 必须用 ref,reactive 做不到。
表单数据对象 (Form Model),reactive,“const form = reactive({ name: ‘’, age: 0 }) 因为表单字段很多,直接 form.name 很方便,且表单通常作为一个整体传递。”
后端返回的列表数据,ref,const list = ref([]) 虽然是数组,但如果后端返回新数组直接替换整个 list,用 reactive 会比较麻烦(不能直接赋值替换,会导致引用丢失),用 ref 直接 list.value = newData 最安全。
更多推荐



所有评论(0)