vue.js 反应性如何依赖 class 可能有很多观察者订阅者

vue.js reactivity how dependency class might have many watcher subscribers

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

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

1) 你能描述一下情况吗 data 属性 其中一个组件可能有 Dep class 而有多个 watcher class?

2) 那么我可以总结如下:如果我们有一个具有 5 个 data 属性的组件。这 5 个数据属性中的每一个都有不同的 Dep class 实例。 Dep class 中的每一个都具有相同的 Watcher 并且 watcher 拥有组件的 render 功能。如果状态发生变化,那 5 个 Dep class 的通知之一会得到 运行 并且那个通知 运行 的 watcher's render 函数?

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

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

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

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

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

渲染进程有一个 Watcher 用于跟踪其数据依赖性。每个组件实例只能获得其中一个。

如果您使用 watch or $watch,也会创建一个 Watcher。同样,您将能够在 _watchers.

中看到这些

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

中更容易看到它们

需要注意的一个关键点是依赖关系被扁平化了。如果您使用计算的 属性 ,您实际上只会依赖于对它有贡献的所有数据属性。您不能直接依赖计算的 属性 本身。

所以回到你原来的问题:

  1. 渲染、计算属性和 watch 都会对 Depsubs 产生影响。由于依赖关系的扁平化,计算属性通常会贡献比您预期更多的订阅者。
  2. 差不多。 render 函数不是直接调用的。当用于渲染的 Watcher 收到数据更改通知时,它实际上只会将组件添加到队列中。直到下一个 tick 开始时才会处理该渲染队列。