Vue 3 响应式原理剖析:从 Ref 和 Reactive 到 Proxy 的魔法揭秘 - 指南
如果你使用过 Vue.js,那么你一定对它的响应式系统赞叹不已——当数据变化时,视图会自动更新。这仿佛是魔法一般。但在 Vue 3 中,这个“魔法”的底层实现完成了一次革命性的升级,从 Vue 2 的 Object.defineProperty 全面转向了 ES6 的 Proxy。
今天,我们就来揭开这层神秘的面纱,深入探讨 ref、reactive 这两个核心 API 以及背后的 Proxy 是如何协同工作,构建出 Vue 3 强大而优雅的响应式系统的。
回顾过去:Vue 2 的 Object.defineProperty 与其局限
在深入 Vue 3 之前,我们先快速回顾一下 Vue 2 的实现方式。Vue 2 使用 Object.defineProperty 来递归地遍历数据对象,将每个属性转化为 getter 和 setter。
javascript
// 简化的 Vue 2 响应式原理
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(`读取了 ${key}: ${val}`);
// 这里进行依赖收集(Dep)
return val;
},
set(newVal) {
if (newVal !== val) {
console.log(`设置了 ${key}: ${newVal}`);
val = newVal;
// 这里通知更新(Watcher)
}
}
});
}
这种方式虽然实用,但存在几个先天缺陷:
无法检测属性的添加或删除:由于是在初始化时遍历属性,因此后来新增的属性不是响应式的(需要用到
Vue.set)。数组响应式需要 hack:直接通过索引设置数组项(
arr[index] = newValue)或修改数组长度(arr.length = 0)无法被检测到。性能开销:递归遍历整个对象、一次性转化所有属性的方式,在初始化时会有一定的性能成本。

浙公网安备 33010602011771号