您可能会发现此介绍很有用:
https://medium.com/dailyjs/tracing-or-debugging-vue-js-reactivity-the-computed-tree-9da0ba1df5f9
正如您所提到的,每个数据属性都有自己的Dep
. 每个Dep
都有一个subs
包含一组订阅者的属性。该数组中的订阅者都将是Watcher
该类的实例。如果数据属性发生变化,则相应的Dep
将Watcher
在其subs
.
每个Watcher
还保存对其依赖项的引用,在一个名为deps
. 这只是订阅的Dep
对象数组。Watcher
您将能够在浏览器开发人员工具中看到这一点。如果你记录一个 Vue 实例,你会发现一个名为的属性_watchers
,它包含与该组件相关的所有观察者。扩展它们deps
将引导您找到Dep
对象,但要准确判断每个对象Dep
代表哪个数据属性可能会很棘手。
渲染进程有一个Watcher
用于跟踪其数据依赖关系的函数。每个组件实例只会获得其中一个。
Watcher
如果您使用watch或$watch ,也会创建A 。再次,您将能够在_watchers
.
计算属性各有一个Watcher
。这些将出现在_watchers
数组中,但更容易在_computedWatchers
.
需要注意的关键是依赖关系是扁平的。如果您使用计算属性,您实际上只会获得对所有贡献它的数据属性的依赖。您不能对计算属性本身形成直接依赖。
所以回到你原来的问题:
- 渲染、计算属性和
watch
都将有助于subs
a Dep
。由于依赖关系的扁平化,计算属性通常会贡献比您预期更多的订阅者。
- 几乎。该
render
函数不是直接调用的。当Watcher
渲染通知数据更改时,它实际上只是将组件添加到队列中。直到下一个滴答开始,才会处理该渲染队列。