vue 代理实现原理
Vue 代理实现原理
Vue 的代理机制主要应用于响应式系统中,通过 Object.defineProperty 或 Proxy 拦截对象属性的访问和修改,实现数据变化时的自动更新。以下是其核心实现原理:
基于 Object.defineProperty 的代理(Vue 2.x)
在 Vue 2.x 中,响应式数据通过 Object.defineProperty 对对象的属性进行劫持,将属性转化为 getter/setter:
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get() {
console.log(`读取属性 ${key}`);
return val;
},
set(newVal) {
if (newVal === val) return;
console.log(`设置属性 ${key} 为 ${newVal}`);
val = newVal;
}
});
}
- 依赖收集:在
getter中收集依赖(如 Watcher),在setter中触发依赖更新。 - 数组处理:需重写数组的变异方法(如
push、pop)以实现响应式。
基于 Proxy 的代理(Vue 3.x)
Vue 3.x 使用 Proxy 替代 Object.defineProperty,能直接代理整个对象并支持动态新增属性:
const reactive = (target) => {
return new Proxy(target, {
get(target, key, receiver) {
console.log(`读取属性 ${key}`);
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
console.log(`设置属性 ${key} 为 ${value}`);
return Reflect.set(target, key, value, receiver);
}
});
};
- 完整拦截:
Proxy支持拦截所有属性操作(包括新增、删除)。 - 性能优化:避免递归遍历对象,仅在访问时处理嵌套属性。
代理在 Vue 中的应用场景
- 响应式数据:
data选项中的对象会被代理,实现数据驱动视图。 - 计算属性:基于依赖的缓存通过代理的
getter实现。 $refs:模板中的ref通过代理动态绑定 DOM 或组件实例。
注意事项
- 性能影响:代理会引入额外的性能开销,需避免过度使用。
- 浏览器兼容性:
Proxy无法被 Polyfill,Vue 3.x 要求环境支持 ES6+。
通过代理机制,Vue 实现了数据与视图的自动同步,开发者只需关注数据逻辑,无需手动操作 DOM。







