vue 监听实现原理
Vue 监听实现原理
Vue 的监听机制主要通过 Object.defineProperty 或 Proxy 实现数据劫持,结合观察者模式(Observer-Watcher-Dep)完成依赖收集和派发更新。

数据劫持
对于 Vue 2.x,使用 Object.defineProperty 递归遍历对象的属性,将其转换为 getter/setter:

function defineReactive(obj, key, val) {
Object.defineProperty(obj, key, {
get() {
console.log('读取属性', key);
return val;
},
set(newVal) {
if (newVal === val) return;
console.log('更新属性', key);
val = newVal;
}
});
}
Vue 3.x 改用 Proxy 代理整个对象,无需递归初始化:
const observed = new Proxy(obj, {
get(target, key) {
console.log('读取属性', key);
return Reflect.get(target, key);
},
set(target, key, value) {
console.log('更新属性', key);
return Reflect.set(target, key, value);
}
});
依赖收集与派发更新
- Observer:递归将数据对象转为响应式,为每个属性创建
Dep实例(依赖管理器)。 - Watcher:在模板编译或手动调用
$watch时创建,触发 getter 时将自身存入当前Dep。 - Dep:维护一个订阅者数组(Watcher 列表),数据变更时通过 setter 触发
dep.notify()通知所有 Watcher 更新。
异步更新队列
Vue 通过 nextTick 实现异步批量更新,避免频繁 DOM 操作。同一事件循环内的多次数据变更会合并为一次视图更新。
监听 API 实现
$watch:内部创建 Watcher 实例,绑定回调函数。watch选项:组件初始化时遍历监听属性,为每个属性创建 Watcher。- 计算属性:基于 Watcher 的惰性求值,依赖变化时标记为脏数据,下次访问时重新计算。






