An overview of the

The purpose of reactive data is to be able to run functions spontaneously when data, object properties, or an array item changes. The most common thing in VUE is to rerun the render function to refresh the page when data changes.

Implementing responsiveness in VUE relies on a few core components

  1. Observer
  2. Dep
  3. Watcher
  4. Scheduler

Observer

The Observer is designed to do a simple job of turning ordinary data into responsive data

  • For objects: hijacking objects is done by recursively calling Object.defineProperty, adding getters and setters for each property so that vUE can be notified to do something when a property is requested or changed. But even then we can’t listen for additions and deletions of object attributes, so vue does$set$deleteInstance method to add or subtract attributes from reactive data
  • In the case of arrays, Vue changes the implicit prototype of the Array to a vUE custom object, overriding some of the original methods that alter the Array so that Vue can listen for changes in the Array’s contents, and finally pointing the implicit prototype of the custom object to array. prototype
Graph LR (Array) - __proto__ -- > B (vue custom object) - B __proto__ - > C (Array. The protoType)

Dep

At this point the data has become responsive data but we have no idea what to do when we read the property, when we modify the property. And the Dep is the vUE that does this. The VUE generates a Dep instance for each responsive data, and the Dep instance does two things

  1. Logging dependencies: When someone accesses this data, it is logged
  2. Distribute updates: Notify all dependencies of changes when data is modified
Graph LR A(getter) -- record dependency --> B(someone use me) C(setter) -->D(I have been changed)

Wather

Now we know that Dep logs dependencies when accessing a response data, but how does the Dep know who actually accessed me

Watcher was designed to solve this problem

When a function runs with response data, Dep has no way of knowing which function is using it, so we hand this function over to Watcher to execute. Watcher sets a global variable to record the current execution of the Watcher. When a Dep logging dependency occurs, the Dep records this global variable, indicating that the current Watcher is using itself. When data changes and Dep sends out an update, Watcher will be notified that I have changed, and Watcher will call the corresponding function again

Every Vue instance has at least one Watcher instance to hold the render function, which Watcher calls to collect dependencies when a Vue component is first rendered

All reactive data used in render will record this Watcher

When the data changes, Dep notifying Watcher and Wather rerunks the Render function to update the dependency.

Scheduler

At this point, vUE responsiveness is almost complete, but there are still some problems.

When Render uses a lot of reactive data, if the reactive data changes, the Watcher for recording render will be called multiple times, wasting a lot of performance. This is clearly unreasonable.

Instead of executing immediately, Watcher actually assigns itself to the Scheduler, which maintains a queue in which the same Watcher can only exist once. Vue provides nextTick methods internally. You can put these watchers into microqueues in an event loop, so the execution of the Watcher is asynchronous

Detailed flow chart