vue watch实现原理
Vue watch 实现原理
Vue 的 watch 机制用于监听数据变化并执行回调函数。其核心原理基于 Vue 的响应式系统和依赖收集机制。
响应式系统基础
Vue 通过 Object.defineProperty(Vue 2)或 Proxy(Vue 3)实现数据的响应式。当数据被访问时,会触发 getter 并收集依赖(Watcher 实例);当数据被修改时,会触发 setter 并通知依赖更新。
Watcher 类的作用
每个 watch 选项会创建一个 Watcher 实例。Watcher 的核心功能包括:
- 在初始化时执行
getter函数(通常是监听的数据的读取操作),触发依赖收集。 - 当依赖的数据变化时,触发
update方法,最终执行用户定义的回调函数。
深度监听的实现
当设置 deep: true 时,Vue 会递归遍历监听对象的所有属性,为每个子属性收集依赖。这样,任意层级的属性变化都能触发回调。
// 简化版的 Watcher 实现示例
class Watcher {
constructor(vm, expOrFn, cb, options) {
this.vm = vm;
this.cb = cb;
this.deep = !!options.deep;
this.deps = [];
if (typeof expOrFn === 'function') {
this.getter = expOrFn;
} else {
this.getter = parsePath(expOrFn); // 解析路径,如 'a.b.c'
}
this.value = this.get();
}
get() {
pushTarget(this); // 标记当前 Watcher 为正在收集的依赖
const value = this.getter.call(this.vm, this.vm);
if (this.deep) {
traverse(value); // 递归遍历对象
}
popTarget(); // 结束依赖收集
return value;
}
update() {
const oldValue = this.value;
this.value = this.get();
this.cb.call(this.vm, this.value, oldValue);
}
}
异步更新队列
Vue 会将 Watcher 的更新推入异步队列(通过 nextTick 实现),避免频繁重复计算和 DOM 操作,提升性能。
与 computed 的区别
computed是惰性求值,只有依赖变化且被访问时才重新计算。watch是主动监听,依赖变化时立即执行回调。
Vue 3 的改进
Vue 3 使用 Proxy 替代 Object.defineProperty,并引入 effect 和 ReactiveEffect 类替代 Watcher,但核心原理类似。







