As you know, for each data property, there's a new Dep
class created. Each Dep
class has subscribers of watchers
.
I looked through vue.js source code and for each component, there's only ONE watcher
class being created which also holds the render
function(template of the component).
1) Could you describe the situation when and why data
property of one of the components might have the Dep
class which has more than one watcher
class?
2) So can I sum up something like this: if we have a component which has 5 data
properties. each of these 5 data properties has different Dep
class instance. and each of those Dep
class has the same Watcher
and that watcher
holds the component's render
function. If state changes, one of those 5 Dep
class's notify gets run and that notify runs its watcher's
render
function?
You may find this introduction useful:
https://medium.com/dailyjs/tracing-or-debugging-vue-js-reactivity-the-computed-tree-9da0ba1df5f9
As you've mentioned, each data property will have its own instance of Dep
. Each Dep
has a subs
property that holds an array of subscribers. The subscribers in that array will all be instances of the Watcher
class. If a data property changes then the corresponding Dep
will notify each Watcher
in its subs
.
Each Watcher
also holds references back to its dependencies, in a property called deps
. This is just an array of the Dep
objects to which the Watcher
is subscribed.
You'll be able to see this in your browser developer tools. If you log a Vue instance you'll find a property called _watchers
that holds all the watchers related to that component. Expanding their deps
will lead you to the Dep
objects, though it can be tricky to tell exactly which data property each Dep
represents.
The rendering process has a Watcher
that it uses to track its data dependencies. You'll only get one of those per component instance.
A Watcher
is also created if you use watch or $watch. Again you'll be able to see these in _watchers
.
Computed properties have one Watcher
each. Those will be present in the _watchers
array but it's easier to see them in _computedWatchers
.
A key thing to note is that dependencies are flattened. If you use a computed property you'll actually just get a dependency on all the data properties that contributed to it. You can't form a direct dependency on the computed property itself.
So to go back to your original question:
watch
will all contribute to the subs
of a Dep
. Computed properties will often contribute more subscribers than you might expect due to the flattening of the dependencies.render
function isn't called directly. When the Watcher
for rendering is notified of a data change it will actually just add the component to a queue. That rendering queue won't be processed until the start of the next tick.