vue watch实现原理

Vue 的 watch 实现原理
Vue 的 watch 功能基于响应式系统的依赖收集和派发更新机制实现。核心原理是通过监听数据变化并触发回调函数。
依赖收集阶段
- 在组件初始化时,Vue 会遍历
watch选项,为每个被监听属性创建对应的Watcher实例。 - 这些
Watcher会将被监听属性添加到自己的依赖列表中。 - 当属性被访问时,触发
getter,Watcher会被当前属性的Dep(依赖管理器)收集。
派发更新阶段
- 当被监听属性发生变化时,触发
setter。 setter会通知对应的Dep,Dep会遍历所有订阅它的Watcher并调用update方法。Watcher的update方法会执行注册的回调函数,并将新旧值作为参数传入。
深度监听实现
- 如果设置了
deep: true,Vue 会递归遍历被监听对象的所有属性。 - 为每个子属性也创建
Watcher,确保嵌套属性变化也能触发回调。
立即触发实现
- 如果设置了
immediate: true,Vue 会在Watcher创建后立即执行一次回调函数。 - 此时旧值为
undefined,新值为当前属性值。
异步更新机制
- 默认情况下,
watch的回调是异步执行的。 - Vue 会将回调推入异步队列,等待当前事件循环结束后统一执行。
- 可以通过
sync: true选项强制同步执行。
源码关键逻辑
// 简化版实现逻辑
function createWatcher(vm, expOrFn, handler, options) {
const watcher = new Watcher(vm, expOrFn, handler, {
deep: !!options.deep,
immediate: !!options.immediate,
sync: !!options.sync
});
if (options.immediate) {
handler.call(vm, watcher.value);
}
return function unwatchFn() {
watcher.teardown();
}
}
与计算属性的区别
watch允许执行异步操作,计算属性必须是同步的。watch更通用,可以监听任何数据变化,计算属性基于其依赖进行缓存。watch没有返回值,计算属性必须返回一个值。
性能优化建议
- 避免过度使用深度监听,特别是大型对象。
- 对于需要监听多个属性的情况,考虑使用计算属性 +
watch的组合。 - 在不需要时及时调用
unwatch函数取消监听。







