【VUE】在vue中,Watcher与Dep的关系
2025年4月17日 15:41
关于vue
中的Watcher
和Dep
的关系讨论。
这两者相互依赖,形成了一个比较完备的响应式系统。
- 一个组件实例对应一个
Watcher(负责视图更新)
- 每个响应式属性,对应一个
Dep
- 计算属性(computed)以及监听器(watch)都会创建各自的 watcher
1.数据属性 & Dep
data() {
return {
count: 0, // 会创建一个 Dep
user: { // user 对象和其每个属性都会创建各自的 Dep
name: 'John', // 一个 Dep
age: 25 // 一个 Dep
}
}
}
对于一个对象,自身有一个Dep,其内在的每个属性都会有一个Dep,所以上述的user对象中,存在3个Dep。
2.watcher的类型
- 每个组件实例,都会创建一个watcher
- 依赖属性存在计算属性computed,也会存在一个watcher
- 监听器watch
3.依赖收集的过程
访问时的过程 ——> getter
<div>{{ count }}</div>
// 渲染 Watcher 执行前,Dep.target 设置为渲染 Watcher
// 访问 count 时:
1. count 的 getter 被触发
2. 将当前 Dep.target (渲染 Watcher) 添加到 count 的 Dep 中
3. 同时这个 Watcher 也会记录这个 Dep
Component Instance
│
├── Render Watcher (负责视图更新)
│ ├── 订阅了 count 的 Dep
│ ├── 订阅了 user.name 的 Dep
│ └── 订阅了其他模板中用到的数据的 Dep
│
├── Computed Watcher (如果有计算属性)
│ ├── 订阅了计算依赖的数据的 Dep
│ └── ...
│
└── User Watcher (如果有 watch 选项)
├── 订阅了被监听数据的 Dep
└── ...
触发更新时的过程 ——> setter
当数据变化时:
- 数据的 setter 被触发
- 通知对应的 Dep
- Dep 通知所有订阅它的 Watcher
- Watcher 根据类型执行不同操作:
- 渲染 Watcher → 触发组件重新渲染
- 计算属性 Watcher → 重新计算
- 用户 Watcher → 执行回调函数
总结起来
一个Watcher中存在多个Dep,依组件中的data中的属性而看
一个Dep中也可存在多个Watcher,如果此时的属性被computed或者watch依赖,那么就会存在多个Watcher