vue watch 实现原理
Vue Watch 实现原理
Vue 的 watch 功能用于监听数据变化并执行回调函数。其核心原理基于 Vue 的响应式系统,通过依赖收集和触发更新机制实现。

依赖收集
在 Vue 的响应式系统中,每个被监听的数据属性会被转换为 getter 和 setter。当初始化 watch 时,Vue 会执行一次 getter 函数,触发依赖收集,将当前 watcher 实例添加到该属性的依赖列表中。

// 简化版依赖收集逻辑
function defineReactive(obj, key) {
let value = obj[key]
const dep = new Dep() // 依赖管理器
Object.defineProperty(obj, key, {
get() {
if (Dep.target) { // 当前正在计算的watcher
dep.addSub(Dep.target)
}
return value
},
set(newVal) {
if (newVal === value) return
value = newVal
dep.notify() // 通知所有依赖更新
}
})
}
Watcher 类
watch 的实现依赖于 Watcher 类。每个 watch 选项会创建一个 Watcher 实例,该实例会在数据变化时触发回调。
class Watcher {
constructor(vm, expOrFn, cb) {
this.vm = vm
this.cb = cb
this.getter = parsePath(expOrFn) // 解析属性路径
this.value = this.get() // 触发依赖收集
}
get() {
Dep.target = this
const value = this.getter.call(this.vm, this.vm)
Dep.target = null
return value
}
update() {
const oldValue = this.value
this.value = this.get()
this.cb.call(this.vm, this.value, oldValue)
}
}
监听触发流程
- 初始化
watch时,创建一个Watcher实例,并立即执行一次get方法,触发属性的getter,完成依赖收集。 - 当监听的属性被修改时,触发
setter,调用dep.notify()通知所有依赖的watcher执行update方法。 update方法中获取新值,并调用用户定义的回调函数。
深度监听实现
对于 deep: true 的深度监听,Vue 会递归遍历对象的所有属性,为每个子属性绑定同样的依赖收集逻辑。
function traverse(value) {
if (typeof value !== 'object') return
for (const key in value) {
traverse(value[key]) // 递归触发getter
}
}
立即触发与异步队列
immediate: true时,会在watch创建后立即执行回调。- 默认情况下,回调会被推入异步队列,确保多次数据变更合并为一次回调执行。
与 computed 的区别
watch是主动监听,适合数据变化时执行异步或开销较大的操作。computed是惰性求值,基于其依赖的响应式数据缓存计算结果。






