1

如您所知,对于每个数据属性,都会new Dep创建一个类。Each Dep类有订阅者watchers

我查看了 vue.js 源代码,对于每个组件,只watcher创建了一个类,它还包含render函数(组件的模板)。

1)您能否描述一下何时以及为什么data其中一个组件的属性可能具有Dep具有多个类的watcher类?

2)所以我可以总结一下:如果我们有一个具有 5 个data属性的组件。这 5 个数据属性中的每一个都有不同的Dep类实例。并且这些Dep类中的每一个都具有相同的Watcher并且watcher包含组件的render功能。如果状态发生变化,这 5 个Dep类的通知之一将运行并且该通知运行其watcher's render功能?

4

1 回答 1

1

您可能会发现此介绍很有用:

https://medium.com/dailyjs/tracing-or-debugging-vue-js-reactivity-the-computed-tree-9da0ba1df5f9

正如您所提到的,每个数据属性都有自己的Dep. 每个Dep都有一个subs包含一组订阅者的属性。该数组中的订阅者都将是Watcher该类的实例。如果数据属性发生变化,则相应的DepWatcher在其subs.

每个Watcher还保存对其依赖项的引用,在一个名为deps. 这只是订阅的Dep对象数组。Watcher

您将能够在浏览器开发人员工具中看到这一点。如果你记录一个 Vue 实例,你会发现一个名为的属性_watchers,它包含与该组件相关的所有观察者。扩展它们deps将引导您找到Dep对象,但要准确判断每个对象Dep代表哪个数据属性可能会很棘手。

渲染进程有一个Watcher用于跟踪其数据依赖关系的函数。每个组件实例只会获得其中一个。

Watcher如果您使用watch$watch ,也会创建A 。再次,您将能够在_watchers.

计算属性各有一个Watcher。这些将出现在_watchers数组中,但更容易在_computedWatchers.

需要注意的关键是依赖关系是扁平的。如果您使用计算属性,您实际上只会获得对所有贡献它的数据属性的依赖。您不能对计算属性本身形成直接依赖。

所以回到你原来的问题:

  1. 渲染、计算属性和watch都将有助于subsa Dep。由于依赖关系的扁平化,计算属性通常会贡献比您预期更多的订阅者。
  2. 几乎。该render函数不是直接调用的。当Watcher渲染通知数据更改时,它实际上只是将组件添加到队列中。直到下一个滴答开始,才会处理该渲染队列。
于 2019-06-29T00:38:19.230 回答