vue observer实现
Vue Observer 实现原理
Vue 的响应式系统核心是通过 Object.defineProperty 或 Proxy 实现的 Observer 模式。以下是关键实现细节:
数据劫持
通过 Object.defineProperty 对对象属性进行劫持(Vue 2.x):
function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log(`读取 ${key}`);
return val;
},
set(newVal) {
if (newVal === val) return;
console.log(`设置 ${key} 为 ${newVal}`);
val = newVal;
}
});
}
Vue 3.x 改用 Proxy 实现:
const reactive = (target) => {
return new Proxy(target, {
get(target, key, receiver) {
track(target, key);
return Reflect.get(target, key, receiver);
},
set(target, key, value, receiver) {
trigger(target, key);
return Reflect.set(target, key, value, receiver);
}
});
};
依赖收集
每个被观察的属性都有一个 Dep 实例,用于存储所有依赖(Watcher):
class Dep {
constructor() {
this.subscribers = new Set();
}
depend() {
if (activeEffect) {
this.subscribers.add(activeEffect);
}
}
notify() {
this.subscribers.forEach(effect => effect());
}
}
观察者模式
通过 Watcher 建立观察者:
let activeEffect = null;
function watchEffect(effect) {
activeEffect = effect;
effect();
activeEffect = null;
}
数组处理
Vue 对数组方法进行特殊处理(Vue 2.x):
const arrayProto = Array.prototype;
const arrayMethods = Object.create(arrayProto);
['push', 'pop', 'shift', 'unshift'].forEach(method => {
const original = arrayProto[method];
arrayMethods[method] = function(...args) {
const result = original.apply(this, args);
dep.notify();
return result;
};
});
实现示例
完整的最小化实现示例:
class Dep {
constructor() { this.subscribers = new Set(); }
depend() { if (activeEffect) this.subscribers.add(activeEffect); }
notify() { this.subscribers.forEach(effect => effect()); }
}
function reactive(obj) {
Object.keys(obj).forEach(key => {
const dep = new Dep();
let value = obj[key];
Object.defineProperty(obj, key, {
get() {
dep.depend();
return value;
},
set(newValue) {
if (newValue !== value) {
value = newValue;
dep.notify();
}
}
});
});
return obj;
}
let activeEffect = null;
function watchEffect(effect) {
activeEffect = effect;
effect();
activeEffect = null;
}
// 使用示例
const state = reactive({ count: 0 });
watchEffect(() => {
console.log(`count: ${state.count}`);
});
state.count++; // 触发重新执行
性能优化
- 避免深层嵌套对象的全量观察
- 采用懒观察策略(Lazy Observation)
- 对不可变数据使用 Object.freeze 跳过响应式处理
- Vue 3 的 Proxy 实现比 Vue 2 的 defineProperty 有更好的性能表现
以上实现展示了 Vue 响应式系统的核心机制,实际源码中还包含更多边界条件处理和优化策略。







