vue observer实现
Vue Observer 实现原理
Vue 的响应式系统核心基于 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x),通过数据劫持实现依赖收集和派发更新。以下是关键实现细节:
数据劫持(Vue 2.x)
通过 Object.defineProperty 递归遍历对象属性,将其转换为 getter/setter:
function defineReactive(obj, key, val) {
const dep = new Dep(); // 依赖管理
Object.defineProperty(obj, key, {
get() {
if (Dep.target) {
dep.depend(); // 收集依赖
}
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify(); // 通知更新
}
});
}
依赖管理(Dep 类)
Dep 类负责管理 Watcher 依赖:
class Dep {
constructor() {
this.subs = [];
}
depend() {
if (Dep.target) {
this.subs.push(Dep.target);
}
}
notify() {
this.subs.forEach(watcher => watcher.update());
}
}
Dep.target = null; // 全局唯一的当前 Watcher
观察者(Watcher 类)
Watcher 是观察者,在数据变化时触发回调:
class Watcher {
constructor(vm, expOrFn, cb) {
this.vm = vm;
this.getter = parsePath(expOrFn);
this.cb = cb;
this.value = this.get();
}
get() {
Dep.target = this;
const value = this.getter.call(this.vm, this.vm);
Dep.target = null;
return value;
}
update() {
const oldValue = this.value;
this.value = this.get();
this.cb.call(this.vm, this.value, oldValue);
}
}
数组响应式处理
Vue 2.x 需特殊处理数组方法(如 push/pop):
const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop', 'shift'].forEach(method => {
const original = arrayProto[method];
arrayMethods[method] = function(...args) {
const result = original.apply(this, args);
const ob = this.__ob__;
ob.dep.notify(); // 手动触发更新
return result;
};
});
Vue 3.x 的 Proxy 实现
Vue 3 使用 Proxy 替代 Object.defineProperty:

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;
}
});
}
关键点总结
- Vue 2.x:基于
Object.defineProperty+ 递归遍历,需处理数组和新增属性的局限性(需用Vue.set)。 - Vue 3.x:基于
Proxy实现深层响应式,支持动态属性和数组变更检测。 - 依赖收集:通过
Dep和Watcher建立数据与视图的关联。 - 性能优化:Vue 3 的响应式模块解耦,支持惰性响应(如
shallowReactive)。






