vue 代理实现原理
Vue 代理实现原理
Vue 的代理机制主要用于实现响应式系统,核心是通过 Object.defineProperty 或 Proxy 拦截对象属性的访问和修改,从而触发依赖收集和更新。
基于 Object.defineProperty 的实现
Vue 2.x 使用 Object.defineProperty 对对象的属性进行劫持。通过递归遍历对象的属性,将其转换为 getter/setter,在属性被访问或修改时触发依赖追踪和更新。
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function() {
console.log('get:', key);
return val;
},
set: function(newVal) {
if (val === newVal) return;
console.log('set:', key, newVal);
val = newVal;
}
});
}
基于 Proxy 的实现
Vue 3.x 使用 Proxy 实现更强大的代理功能。Proxy 可以直接代理整个对象,无需递归遍历属性,且能拦截更多操作(如数组方法、属性删除等)。
const handler = {
get(target, key) {
console.log('get:', key);
return Reflect.get(target, key);
},
set(target, key, value) {
console.log('set:', key, value);
return Reflect.set(target, key, value);
}
};
const proxy = new Proxy({}, handler);
依赖收集与触发更新
无论是 Object.defineProperty 还是 Proxy,核心目标都是实现依赖收集和更新触发:
- 依赖收集:在 getter 中记录当前正在执行的 Watcher。
- 触发更新:在 setter 中通知所有依赖的 Watcher 执行更新。
// 简化的依赖收集逻辑
class Dep {
constructor() {
this.subscribers = new Set();
}
depend() {
if (currentWatcher) {
this.subscribers.add(currentWatcher);
}
}
notify() {
this.subscribers.forEach(watcher => watcher.update());
}
}
总结
Vue 的代理实现原理是通过拦截对象属性的访问和修改,结合依赖收集机制,实现数据变化时的自动更新。Vue 2.x 使用 Object.defineProperty,而 Vue 3.x 升级为 Proxy,提供了更全面的拦截能力和性能优化。







