vue observer实现
Vue Observer 实现原理
Vue 的响应式系统核心是通过 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)实现的 Observer 模式。以下是关键实现细节:
Vue 2.x 的 Observer
数据劫持
通过 Object.defineProperty 递归地将对象的属性转换为 getter/setter:
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log('get:', key);
return val;
},
set(newVal) {
if (newVal === val) return;
console.log('set:', key);
val = newVal;
}
});
}
依赖收集 每个属性维护一个 Dep 实例,用于存储依赖(Watcher):
class Dep {
constructor() {
this.subs = new Set();
}
addSub(sub) {
this.subs.add(sub);
}
notify() {
this.subs.forEach(sub => sub.update());
}
}
Observer 类 递归观测整个对象:
class Observer {
constructor(value) {
this.walk(value);
}
walk(obj) {
Object.keys(obj).forEach(key => {
defineReactive(obj, key, obj[key]);
});
}
}
Vue 3.x 的 Observer
Proxy 实现
改用 Proxy 实现数据劫持,解决 Vue 2.x 的局限性(如数组检测、新增属性等):
function reactive(obj) {
return new Proxy(obj, {
get(target, key, receiver) {
track(target, key); // 依赖收集
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
Reflect.set(target, key, value, receiver);
trigger(target, key); // 触发更新
return true;
}
});
}
Effect 系统
使用 effect 替代 Watcher,基于 Proxy 的响应式更高效:

let activeEffect;
function effect(fn) {
activeEffect = fn;
fn();
activeEffect = null;
}
关键差异对比
- 性能:Proxy 无需递归初始化全部属性,按需响应
- 数组处理:Proxy 直接支持数组索引修改和
push等方法 - API 设计:Vue 3.x 的
reactive/ref更灵活,兼容组合式 API
实现注意事项
- 避免循环引用导致栈溢出
- 对
__proto__等特殊属性需做安全处理 - 嵌套对象的深度观测需要惰性化以优化性能
完整实现需结合虚拟 DOM 和调度系统,但以上代码已展示核心响应式原理。实际开发中建议直接使用 Vue 提供的 API,而非手动实现。






