vue watch 实现 原理
Vue Watch 实现原理
Vue 的 watch 机制是基于响应式系统的核心功能之一,用于监听数据变化并执行回调函数。其实现原理主要依赖以下几个关键点:
依赖收集与触发
Vue 的响应式系统通过 Object.defineProperty 或 Proxy(Vue 3)劫持数据的访问和修改。当在 watch 中监听某个属性时,Vue 会将该属性的依赖(即 watcher 实例)添加到依赖列表中。
- 初始化阶段:
watch选项会被解析,为每个监听属性创建一个watcher实例。 - 数据访问时:触发
getter,将当前watcher添加到依赖列表中(Dep类管理)。 - 数据修改时:触发
setter,通知所有依赖的watcher执行更新。
Watcher 类
Watcher 是 Vue 内部用于管理依赖的核心类,watch 的每个监听项对应一个 watcher 实例。其主要职责包括:

- 记录监听的目标属性(或表达式)。
- 保存回调函数(
handler)及其配置(如deep、immediate)。 - 当目标属性变化时,调用回调函数。
// 伪代码:Watcher 的基本逻辑
class Watcher {
constructor(vm, expOrFn, handler, options) {
this.vm = vm;
this.getter = parsePath(expOrFn); // 解析属性路径(如 'a.b.c')
this.handler = handler;
this.deep = !!options.deep;
this.value = this.get(); // 首次触发依赖收集
}
get() {
pushTarget(this); // 将当前 watcher 设为全局依赖
const value = this.getter.call(this.vm, this.vm); // 触发属性的 getter
if (this.deep) traverse(value); // 深度监听时递归遍历子属性
popTarget(); // 恢复上一个 watcher
return value;
}
update() {
const oldValue = this.value;
this.value = this.get(); // 重新获取值
this.handler.call(this.vm, this.value, oldValue); // 执行回调
}
}
深度监听(deep: true)
当配置 deep: true 时,Vue 会递归遍历监听对象的所有子属性,为每个子属性绑定相同的 watcher。这是通过递归调用 traverse 函数实现的:
function traverse(val) {
if (typeof val !== 'object') return;
for (const key in val) {
traverse(val[key]); // 递归触发子属性的 getter
}
}
立即执行(immediate: true)
若配置 immediate: true,Vue 会在 watcher 创建时立即执行一次回调函数,此时 oldValue 为 undefined。

异步更新队列
Vue 会将 watcher 的更新推入异步队列(nextTick 机制),避免频繁触发重复更新。这是通过 queueWatcher 方法实现的:
function queueWatcher(watcher) {
const id = watcher.id;
if (!has[id]) {
has[id] = true;
queue.push(watcher);
nextTick(flushQueue); // 异步执行所有 watcher 的更新
}
}
总结
Vue 的 watch 实现依赖于响应式系统的依赖收集和触发机制,通过 Watcher 类管理监听逻辑,结合深度监听和异步更新队列优化性能。其核心流程为:
- 初始化时为每个监听属性创建
watcher。 - 数据访问时收集依赖,数据修改时触发
watcher更新。 - 通过
deep和immediate配置扩展功能。






