在 Vue 的响应式系统中,Observer
、Watcher
和 Dep
是三个核心概念,它们共同工作以实现数据的响应式更新。以下是这三者之间的关系和作用:
1. Observer
- 作用:
Observer
是一个对象,用于将普通的 JavaScript 对象转换为响应式对象。它会遍历对象的属性,并使用Object.defineProperty
或 Proxy 来劫持这些属性的读写操作。 - 功能: 当数据被访问或修改时,
Observer
会通知相关的Dep
,以便进行依赖收集和更新。
2. Dep
- 作用:
Dep
是一个依赖管理器,用于收集和管理所有依赖于某个响应式属性的Watcher
实例。 - 功能: 当响应式属性发生变化时,
Dep
会通知所有依赖于该属性的Watcher
,以便它们可以重新计算和更新视图。
3. Watcher
- 作用:
Watcher
是一个观察者,用于观察响应式数据的变化。每个Watcher
实例都与一个特定的组件或计算属性相关联。 - 功能: 当
Watcher
被创建时,它会在Dep
中注册自己,并在数据变化时接收通知,从而触发视图的更新。
关系
- 数据流: 当你访问一个响应式属性时,
Observer
会通过Dep
收集依赖的Watcher
。当这个属性的值发生变化时,Dep
会通知所有相关的Watcher
,从而触发视图的更新。 - 依赖收集:
Watcher
在创建时会触发 getter,从而使Dep
收集到这个Watcher
。当数据变化时,Dep
会调用所有注册的Watcher
的更新方法。
总结
Observer
负责将对象变为响应式。Dep
负责管理依赖关系。Watcher
负责响应数据变化并更新视图。- 当首次访问数据或者使用object.defineProperty创建响应式对象时,会创建Watcher,与此同时Observer会将对象变为响应式(如果是创建对象时),当访问数据时会触发getter事件,Observer检测到getter事件后会通知Dep去收集依赖(将对应的Watcher收集),当检测到setter事件时,通知Dep去执行Watcher的回调
- 而在vue3中使用了proxy去代理数据,proxy可以拦截数据的变化,并通知dep去收集依赖或更新视图,代替了Observer的功能