实现简易vue响应式
实现简易 Vue 响应式系统
Vue 的响应式系统核心是通过 Object.defineProperty 或 Proxy 拦截数据变化,并结合依赖收集与派发更新机制实现。以下是一个基于 Object.defineProperty 的简化实现:

数据劫持(Observer)
通过递归遍历对象属性,将其转换为响应式:

function observe(data) {
if (typeof data !== 'object' || data === null) return;
new Observer(data);
}
class Observer {
constructor(data) {
this.walk(data);
}
walk(data) {
Object.keys(data).forEach(key => {
defineReactive(data, key, data[key]);
});
}
}
function defineReactive(obj, key, val) {
observe(val); // 递归处理嵌套对象
const dep = new Dep(); // 每个属性对应一个依赖管理器
Object.defineProperty(obj, key, {
get() {
Dep.target && dep.addSub(Dep.target); // 收集依赖
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
observe(newVal); // 新值是对象时继续劫持
dep.notify(); // 触发更新
}
});
}
依赖管理(Dep)
管理所有依赖(Watcher)并在数据变化时通知:
class Dep {
constructor() {
this.subs = [];
}
addSub(sub) {
this.subs.push(sub);
}
notify() {
this.subs.forEach(sub => sub.update());
}
}
Dep.target = null; // 全局标记当前正在计算的Watcher
观察者(Watcher)
封装依赖更新逻辑:
class Watcher {
constructor(vm, key, cb) {
this.vm = vm;
this.key = key;
this.cb = cb;
Dep.target = this;
this.oldValue = vm[key]; // 触发getter收集依赖
Dep.target = null;
}
update() {
const newValue = this.vm[this.key];
if (newValue !== this.oldValue) {
this.cb(newValue);
this.oldValue = newValue;
}
}
}
使用示例
const data = { count: 1 };
observe(data);
new Watcher(data, 'count', (val) => {
console.log(`count更新为: ${val}`);
});
data.count = 2; // 输出: "count更新为: 2"
注意事项
- 数组变异方法需要特殊处理(如
push/pop等) - 现代 Vue 版本已改用
Proxy实现,可避免Object.defineProperty的局限性(如新增属性检测) - 实际实现还需处理虚拟DOM、批量更新等复杂逻辑






