computed

Throw out problem

  1. When computed is created and what computed does

  2. How does a computed key render access trigger its GET

  3. What does a computed Watcher create process do

  4. What is the unclear dependence between page P and computed A and data B

  5. How do I rerender the page after data B changes

  6. What is the relationship between lazy and dirty

When computed is created and what computed does

  1. When initState, it handles various options, including handling computed

if (opts.computed) initComputed(vm, opts.computed)

  1. initComputed

The function first creates vm._computedWatchers as an empty object, then iterates through a computed object, and gets the value of each key for the computed property. If it is a function, it assigns the value to the getter; otherwise, it gets the get property and assigns the value to the getter.

Error if getter == null.

Next create a computer Watcher for each getter passing in the note computedWatcherOptions = {lazy:true}.

If the key is not a vm attribute, call defineComputed(VM, key, userDef). If not, call defineComputed(VM, key, userDef). If not, call defineComputed(VM, key, userDef).

  1. defineComputed

DefineProperty is used to add a getter and setter for the key value of the calculated property. Setters are usually available when the calculated property is an Object and has a set method, otherwise it is an empty function. In normal development scenarios, it is rare to have a setter for a calculated property. The final getter corresponds to the return value of the createComputedGetter(key).

  1. createComputedGetter

CreateComputedGetter Returns a function computedGetter, which is the getter for the calculated property. This is the end of the initialization process for the calculated properties.

How does a computed key render access trigger its GET

As you can see above, the key is subscribed to by calling Object.defineProperty, and the sharedPropertyDefinition is an Object with a get function computedGetter() inside it. Because it’s subscribed it’s going to call GET when it renders to the key.

What does a computed Watcher create process do

You can see that computed watcher does not evaluate immediately because lazy is true, and notice that lazy is assigned to dirty.

What is the unclear dependence between page P and computed A and data B

  1. guess

Theoretically B depends on A and A depends on P -> so A collects THE Watcher of P and B collects the Watcher of A. In theory, when Data B changes, computed Watcher is notified to update, and computed Watcher informs the page Watcher to update.

  1. However, the reality is often very cruel

B depends on A and A depends on P -> Actually B collects the Watcher of A and the Watcher of P. When Data B changes, computed Watcher is notified to update, and Data B notifies the page Watcher to update. (Can’t help but say wonderful, wonderful, wonderful)

???? How did the black question mark Data B collect P’s Watcher?

When the start page initializes, Create the page Watcher, the getter for the page Watcher is updateComponent, execute this.get() when creating the page Watcher, targetStack pushes the page Watcher, dep. target assigns the page Watcher, and execute g Etter, which performs updateComponent (vm._render in computed key), fires the key get (computedGetter() function above) because the key is responsive.

  1. computedGetter

There are two steps here

  • The first step

Component Watcher: component Watcher: component Watcher: component Watcher: component Watcher: component Watcher: component Watcher: component Watcher: component Watcher: component Watcher Then set this.dirty to false. During the evaluation, this. Getter. Call (vm, vm) is executed, which is essentially performing the calculation of the value of the property key, which is executing the callback that we wrote, and since data B is reactive, when we access it, we’re going to fire its GET. Trigger Dep.depend (),targetStack pushes component Watcher, dep. target assigns component Watcher, and data B collects component Watcher. At this point, popTarget() continues to pull out computed Watcher in targetStack, and dep.watcher is the page PWatcher, and then step 2!

  • In the second step, if dep. Watcher exists, execute watcher.depend, call dep. Depend, and the result is that page Watcher is added to the dep.subs of the key, so there is computed and page Watcher in the key. This one in, one out, like that Hasegay!

The vm._update node is added to the page after the dependencies are collected.

What is the unclear dependence between page P and computed A and data B

So data B collects computed Watcher and page P Watcher, but there are two suitors and they’re not in that kind of relationship. Sit down.

How do I rerender the page after data B changes

If data B changes, set is triggered. If data B is modified, set is returned unchanged.

The value changes the assignment and triggers dep.notify() to re-render. Dep.notify () is the update call to watcher.

Then trigger update for computed Watcher and the Watche page. For a computed Watcher update, simply get this.dirty = true! The Watche update will execute queueWatcher(), which will execute watcher’s run. Watcher. Run will call this.get(), then pushTarget(this), And then you execute the getter which is updateComponent! The next thing you know is to repeat the render fetch process.

What is the relationship between lazy and dirty

Dirty indicates whether the cache is available. If it is true, the cache is dirty and needs to be recalculated. Otherwise, it is not used. Dirty defaults to false, while lazy assigns an initial value to dirty, which means that you’ve started controlling the cache. So remember, dirty is what really controls the cache, and lazy is just an enabler.

conclusion

To us on a hemp flower hard vegetables to see the cry of this picture of the point like it, ha ha ha ha ha!

1. If computed is defined in InitState, there will be an initComputed operation. InitComputed first creates empty object Watchers and vm._computedWatchers. Then, through the user-defined computed algorithm, the value corresponding to the key is obtained. If value is a function, the value is directly assigned to the getter; otherwise, the get attribute of the value is assigned to the getter. Then check if the getter exists or does not exist and report an error. Then add the key property to the created Watchers object with a value of new Watcher instance.

2. The new Watcher instance passes in the getter that is the callback and the computedWatcherOptions configuration item to set lazy to true.

3.Watcher first assigns the passed lazy to this.dirty. It then passes the getter, the callback, to this.getter. Then this.get() is not executed immediately because this.lazy is true.

4. Go back to initComputed and finally handle the conflict between key values in computed and data. If there is a conflict, an error is reported.

DefineComputed, the sharedPropertyDefinition object sets enumerable, 64x, get, and set properties of the object. Then determine whether the value passed is a function, if it is a function that sets the get of sharedPropertyDefinition to createComputedGetter(key). If it’s not a function then it’s an object. If the value has a get function, set the get of sharedPropertyDefinition to createComputedGetter(key). If the value has a set function, Set the set of sharedPropertyDefinition to value.set.

6. CreateComputedGetter This returns a computedGetter function waiting to be fired.

7. Back to defineComputed, Object. DefineProperty (Target, key, sharedPropertyDefinition) is finally called to perform a responsive processing for computed current keys on the VM instance. Set the get for key to createComputedGetter.

This. Get () will set dep. Watcher to page Watcher and drop the page Watcher into the targetStack queue. Perform the getter, updateComponent, vm._update(vm._render(), hydrating)}, and then perform the get method for computed keys that render resolves to computed keys. That’s what triggers the createComputedGetter.

9. The createComputedGetter obtains the _computedWatchers object of the instance (as in the first step above) from the key and obtains the cached Watcher. The watcher.evaluate() method is called. The second step is to determine if dep.target exists, and if so, the watcher.depend() method is called. Finally, return watcher.value.

10. Evaluate: first set value to this.get(), then set dirty to false. This.get () performs pushTarget(this) as its name implies first to set emp.watcher to computed Watcher and to throw computed Watcher into the targetStack queue. This.getter () is then executed. The getter here is no longer updateComponent but computed Key creating a callback for computed Watcher passing in the key. A callback that accesses new data triggers a GET for new data, returns the value first and then checks whether there is a dep. target, in which case the dep. target is computed Watcher, and calls dep.depend(). Finally, computed Watcher is collected in the subs array of the new DEP data. This. Getter is done, followed by a popTarget operation, computed Watcher, the last bit of the targetStack, and then set dap. Watcher to page PWatcher. Then there is cleanupDeps cleanup optimization.

If there is a dep.target page Watcher, it will execute the watcher.depend() method, first iterating through the deps to call their respective depend methods. The result is that a page Watcher is added to the dep.subs of this key, so there is computed and page Watcher for this key at this time.

PopTarget is executed, the last bit of the targetStack is the page Watcher, and dep. Watcher is set to null. Then there is cleanupDeps cleanup optimization. Collecting dependencies is complete.

13. When the set method is triggered to modify data, it first checks whether the value has changed. In order to change, it returns watcher.update if the dep.notify() notification is triggered. Then set dirty to true to end. Watcher performs queueWatcher for the page, finally performs watcher.run performs this.get() performs the getter performs updateComponent, and then render resolves to get methods for computed keys that trigger keys. That’s what triggers the createComputedGetter. This is followed by the createComputedGetter action above.