vue watch实现过程
Vue Watch 的实现过程
Vue 的 watch 用于监听响应式数据的变化,并在数据变化时执行回调函数。以下是其核心实现过程:
初始化 Watcher
在 Vue 实例初始化阶段,如果组件选项中定义了 watch,会遍历这些监听属性,为每个属性创建一个 Watcher 实例。Watcher 是 Vue 响应式系统的核心之一,负责依赖收集和触发更新。
// 简化版 Watcher 初始化逻辑
function initWatch(vm, watch) {
for (const key in watch) {
const handler = watch[key];
createWatcher(vm, key, handler);
}
}
依赖收集
当 Watcher 被创建时,会执行一次 getter 函数(即监听属性的值),触发数据的 get 拦截器。此时,Watcher 会被添加到当前属性的依赖列表(Dep)中。
// 依赖收集核心逻辑
class Dep {
constructor() {
this.subs = [];
}
depend() {
if (Dep.target) {
this.subs.push(Dep.target);
}
}
notify() {
this.subs.forEach(watcher => watcher.update());
}
}
触发更新
当监听的属性值发生变化时,会触发 set 拦截器,调用 Dep.notify() 通知所有依赖的 Watcher 执行更新。Watcher 会根据配置(如 deep、immediate)决定是否执行回调函数。
// Watcher 更新逻辑
class Watcher {
update() {
if (this.lazy) {
this.dirty = true;
} else {
this.run();
}
}
run() {
const value = this.get();
if (value !== this.value || this.deep) {
this.cb.call(this.vm, value, this.value);
this.value = value;
}
}
}
深度监听(deep: true)
如果设置了 deep: true,Watcher 会递归遍历监听对象的所有子属性,为每个子属性也绑定依赖收集逻辑。
// 深度监听实现片段
function traverse(val) {
if (typeof val !== 'object') return;
for (const key in val) {
traverse(val[key]);
}
}
立即触发(immediate: true)
若配置了 immediate: true,Watcher 会在创建时立即执行一次回调函数,而非等待数据变化。
// immediate 处理逻辑
if (this.immediate) {
this.cb.call(this.vm, this.value, null);
}
总结
Vue 的 watch 通过 Watcher 机制实现,核心流程包括依赖收集、派发更新和回调执行。通过 deep 和 immediate 等配置项,可以扩展其监听行为。







