【问题标题】:vue.js reactivity how dependency class might have many watcher subscribersvue.js 反应性依赖类如何可能有许多观察者订阅者
【发布时间】:2019-06-28 09:15:54
【问题描述】:

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

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

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

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

【问题讨论】:

  • 嗨,乔治·拉吉泽。你能用示例数据更多地解释你的用例吗?

标签: vue.js vuejs2 vue-component vue-reactivity


【解决方案1】:

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

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

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

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

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

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

如果您使用watch$watch,也会创建一个Watcher。同样,您将能够在 _watchers 中看到这些。

每个计算属性都有一个Watcher。这些将出现在_watchers 数组中,但在_computedWatchers 中更容易看到它们。

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

所以回到你原来的问题:

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

【讨论】:

  • 嘿skitlele,你已经很久没有回答这个问题了。我还有一个问题,如果你不介意的话。如果数据属性的变化也改变了计算属性,我们将有 2 个必须运行的观察程序类。 1) 组件观察者渲染 2) 计算观察者.. 这两个是我们更改的数据属性的订阅者,所以这两个观察者被添加到队列中。我的问题是,观察者渲染类应该始终是队列中的最后一个,因为我们可能在模板中使用计算,所以首先,我们必须运行计算观察者,然后最后渲染观察者。对吗?
  • @NikaKurashvili 计算属性的观察者不需要通过队列。他们只是立即使缓存值无效。直到有东西试图访问它时才会计算计算属性的新值。
  • 所以,在队列中,只有渲染观察者结束了?
  • 因此,如果我有一个具有 2 个观察者(渲染观察者、计算观察者)的数据属性,并且我在某个函数中更改了此数据属性,则会发生 vue 将运行除渲染观察者之外的所有观察者。运行它们后,所有值都将更改。然后,作为最后一步,渲染观察器将被添加到队列中,对吗?
猜你喜欢
  • 2016-06-26
  • 1970-01-01
  • 1970-01-01
  • 2018-06-11
  • 2019-02-07
  • 1970-01-01
  • 1970-01-01
  • 2015-02-24
  • 1970-01-01
相关资源
最近更新 更多