The foreword 0.

Vue’s responsiveness can be said to be a point that the front-end interview must ask, so this time I want to use my own words to describe the implementation principle of responsiveness.

Some of the keywords mentioned in this article

  • Dependent collection objectsdep
  • subsAn array of
  • settermethods
  • renderWatcher.computedWatcher.userWatcher
  • .

1. Responsive dataRely onandBe dependent on

Suppose you have the following Vue single page:

<template> <h1>count :{{count}}</h1> <h1>2 times count :{{doubleCount}}</h1> </template> <script> export default { data() { return { count: 97, }; }, computed: { doubleCount() { return this.count * 2; ,}}}; </script>Copy the code

The page is very simple, a reactive count, a calculated property doubleCount, and both are rendered on the view. But in a more professional way, this example shows dependency and dependency in the title:

  1. The view usesdoubleCountThis is the calculation of propertiesBe dependent on
  2. The calculated properties use reactive datacountThis is the calculation of propertiesRely on

With these two things in mind, the implementation principle of responsiveness can be explained.

2. Implementation principle of responsive data

The results of the responsive data are as follows:

When a responsive data (whether data or computed) is relied on, the dependent pushes its corresponding Watcher into the subs array of the dependent, where the watcher of the view is renderWatcher. The watcher of the calculated attribute is a calculated watcher, and the watcher in the watch option defined by the user is called the userWatcher

Depend on the collection

When count is used in the template, the view depends on the reactive count. When the VUE is initialized, the view’s renderWatcher is added to the subs array of the DEP object defined by the reactive count in the closure. Of course, the same process goes for calculating attributes, which is also called dependency collection in Vue.

Distributed update

When the count value is reset, the setter method of Object.definePorperty is triggered, which calls notify of the DEP Object. What this notify method does is iterate through each of the Watcher’s calls to their own Update method in the subs array.

  • forrenderWatcherSpeaking,updateThe method is to callrenderFunction generates newVNodevirtualdomAnd then callpatchMethod to install a patchdiffAlgorithm for old and new virtualdomCompare to find the smallest changes, and then update the real one at a timedomThe view is updated.
  • forcomputedWatcherSpeaking,updateMethods are user-defined functions that evaluate properties.
  • foruserWatcherSpeaking,updateMethods are also user-defined callback functions.

3. Implementation principle of computing attributes

In fact, if you can understand the above Vue responsivity principle, calculated attributes have the same nature, can be analogized, of course, the interview often mentioned the caching mechanism of calculated attributes.

When someone reads the value of the calculated property, it actually reads the value. The update method of the calculated property is called only when the dependency of the calculated property changes, thus updating the value. Multiple reads of the value of the calculated property will fetch the value of value without triggering the callback function, thus implementing caching. This is also the most important difference between computed attributes and functions. If the caching mechanism of computed attributes is not considered, computed attributes can be completely replaced by functions defined in ordinary methods.

The workflow for calculating attributes is as follows:

Computational properties depend on others, and when others change, they change, too

When a calculated attribute depends on others (for example, the calculated attribute doubleCount uses count), doubleCount will submit its computedWatcher to the subs array of the DEP object inside count. When count changes, The dispatch update process mentioned in the previous section is triggered, which eventually invokes the computedWatcher update method to update the value of the calculated property.

The calculated property is dependent on others, and when you change it, you notify others of the change

Then, when the calculated property is used in the view, since the view has added its renderWatcher to the subs array of the calculated property’s DEP object during initialization, when the calculated property value changes, the calculated property will compare the old and new values. If the value changes, It iterates through the notify method of its own DEP object and finally completes the view update.


Computed attributivedirty

Finally, calculate the dirty of the attribute. This attribute also calculates the internal value of the attribute. It does the following:

When the dependency of the calculated property changes, instead of performing the update evaluation of the calculated property immediately, I set my dirty to true to indicate that I am contaminated. When the dirty is true, the update method will update the value again, which is lazy update and cache.