您可能会发现此介绍很有用:
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都将有助于subsa Dep。由于依赖关系的扁平化,计算属性通常会贡献比您预期更多的订阅者。
- 几乎。该
render函数不是直接调用的。当Watcher渲染通知数据更改时,它实际上只是将组件添加到队列中。直到下一个滴答开始,才会处理该渲染队列。