Asynchronous update queue

  1. There are three kinds of watcher

    • Render Watcher, change can directly change the view
    • Computed Watcher, change the view after the computation
    • Regular Watcher, what is this?
  2. Asynchronous queue

    • When a data changes ten times in a row, does Watcher have to update it ten times?
    • Will Watcher execute updates as soon as they are executed?
    • What is the order of execution for multiple Watchers? Is it all first come, first served?

      — No, three rules are officially defined for execution order, sorted by ID, so how is this ID assigned?

      • The parent component is updated before the child component, because the parent component is created before the child component
      • Update a component firstuser watchersAnd update hisrender watchers
      • If a component is destroyed when the parent component is updated, skip the component

      How are ids assigned? When watcher is first created, it assigns an ID. The larger the ID, the younger it is. Sorting by ID guarantees the above three rules

      When were the terms render watcher and use watcher defined?

  3. zhuanlan.zhihu.com/p/72494035

Vue is executed asynchronously when updating the DOM. As long as it listens for data changes, Vue opens a queue and buffers all data changes that occur in the same event loop. If the same watcher is triggered more than once, it will only be pushed into the queue once. This removal of duplicate data while buffering is important to avoid unnecessary computation and DOM manipulation

  • The asynchronous queue method queueWatcher

    1. Check whether it is already in the queue by id first
    2. If it doesn’t put it in the queue,flushing

A deferred callback is performed after the next DOM update loop ends. Use this method immediately after modifying the data to get the updated DOM.

The role of flushSchedulerQueue

Watcher updates the queue in ascending order

2. Traverse the Watcher update queue and call watcher updates one by one

3, Watcher update queue completed, reset the status

  // Sort queue before flush.
  // This ensures that:
  // 1. Components are updated from parent to child. (because parent is always
  //    created before the child)
  // 2. A component's user watchers are run before its render watcher (because
  //    user watchers are created before the render watcher)
  // 3. If a component is destroyed during a parent component's watcher run,
  //    its watchers can be skipped.
Copy the code
Why is it in ascending order?
export function queueWatcher (watcher: Watcher) { const id = watcher.id if (has[id] == null) { has[id] = true if (! flushing) { queue.push(watcher) } else { // if already flushing, splice the watcher based on its id // if already past its id, it will be run next immediately. let i = queue.length - 1 while (i > index && queue[i].id > watcher.id) { i-- } queue.splice(i + 1, 0, watcher) } // queue the flush if (! waiting) { waiting = true if (process.env.NODE_ENV ! == 'production' && ! config.async) { flushSchedulerQueue() return } nextTick(flushSchedulerQueue) } } }Copy the code

At what stage

It’s in the initState phase

The deP is in the initData stage

$Mount phase on New Watcher

If it is called in the template, it must have a render Watcher

Cache for dirty and computed

Proxy

Let’s look at proxies

Proxy objects are used to define custom behavior for basic operations (such as property lookup, assignment, enumeration, function call, etc.)

An interception is placed before an object, which must pass through whenever a listening object is accessed. In this interception, you can process the original object and return the required data format, that is, whatever attributes of the object are accessed, previously defined or newly added, will be processed in the interception. This solves the problem of not being able to listen before.

If you add or edit attributes, you don’t need to add reactive processing, because Proxy is an operation on an object, and as soon as you access an object, you go to the logic of Proxy. Reflect is a built-in object that provides methods to intercept JavaScript operations. These methods are the same as the proxy Handlers method. Reflect is not a function Object, so it is not constructible. The way Proxy and Object.defineProperty are used seems similar, but Proxy intercepts attributes at a higher level.

Object. DefinePropertyVue2, for a given data: such as} {count: 1, according to specific needs is the key which the count, to get and set to intercept, namely:

www.itheima.com/news/202008…

You must know what key to intercept in advance, which is why Vue2 can’t do anything about new attributes on the object, so the initialization process of Vue needs to traverse data to capture data changes, resulting in slow speed and large memory.

Proxy the Proxy used by Vue3 intercepts like this:

new Proxy(data, {
  get(key) { },
  set(key, value) { },
})
Copy the code

As you can see, the proxy does not need to care about the specific key. What it intercepts is modifying any key on data and reading any key on data

So, both existing keys and new keys will be listened to.

computed

Juejin. Cn/post / 689793…

\