Directly above

Take a

  1. First find the entry that responds
    • Find the entry in the source code/core/instance/state.jsInitData, which is executed when data is initialized, is found in this method and executedobserver(data)Method, this is the entrance
  2. Then seeobserver(data)What did you do, at/core/observer/index.js
    • First, I did some judgment work, whether it is an object, whether it is a VNode object, etc., and skipped directly
    • Importantly: an Observer object is instantiated
  3. Next, look at the instance constructorObserverWhat is it
    • Found that in the case of the object, a walk method was executed
    • One is executed for each piece of datadefineReactiveI finally found the key
  4. Take a look atdefineReactivemethods
    • Let’s just look at the key points and skip the details (too many)
    Object.defineProperty(obj, key, {
        enumerable: true.configurable: true.get() { 
            // Collect dependencies here
            if (Dep.target) {
                dep.depend()
            }
        },
        set() {
            // Trigger dependency updates here
            dep.notify()
        }
    })
    Copy the code
  5. It’s over. I can’t go on
Then look at the picture 😂, according to the serial number of the picture then say

First, the green collection dependency

  1. I’m going to create an instance of Watcher, and what’s watcher, it looks like that’s where you’re going to use data, so that’s the way to think about it

  2. Target = this assigns dep. target to the current new instance of Watcher

  3. Dep. Append for dependency collection to see what is going on in the Dep

      depend () {
       if (Dep.target) {
         // Set dep. target to a watcher instance
         // So execute the addDep method on Watcher and pass the current deP instance as an argument
         Dep.target.addDep(this)}}Copy the code
  4. Go inside the Watcher constructor and execute the addDep method

        // A little dizzy,
        addDep(dep) {
            dep.addSub(this)}Copy the code
  5. The discovery is back in the DEP, execute its addSub method, and place watcher in the defined sub list

I’m a little confused here, collecting dependencies, so first the DEP calls the Append method, and then it calls the addDep method on Watcher, and watcher, The addDep method calls the Dep method to put watcher in the sub list. dep.append –> watcher.addDep(dep) –> dep.addSub(watcher); The watcher collection is finally implemented in the DEP

And the blue trigger update

  1. dep.notifyExecute the update method in DEP to iterate through all the places where the variable is used previously collected and call the update method
        notify() {
             for (let i = 0, l = subs.length; i < l; i++) {
              // Execute the update method in each watcher to update the data
              subs[i].update()
            }
        }
    Copy the code
  2. Execute the update method on the Watcher instance,
  3. QueueWatcher puts changes into a queue, waiting for updates

Array update

Since the obejct.defineProperty method cannot read the array changes, our goal is to solve the problem of knowing that the array has changed so that we can update the view accordingly and see that the separate methods in the source code are roughly integrated

    if (Array.isArray(value)) {
      // Determine if there is a __proto__ attribute
      if (hasProto) {
        // Overwrite the original prototype of the array so that the array is responsive
        value.__proto__  = arrayMethods
      } else {
        // If there is no __proto__ attribute, there is no prototype, and the modified data is directly changed to the array itself
        const arrayKeys = Object.getOwnPropertyNames(arrayMethods)
        for (let i = 0, l = arrayKeys.length; i < l; i++) {
          const key = arrayKeys[i]
          value.key = arrayMethods[key]
        }
      }
      // This is an object that listens on if the array element is an object
      this.observeArray(value)
    }
Copy the code

You can see that there are two ways to handle an array method. If there is a stereotype, override the method on the prototype chain. If there is no stereotype, change the current method to an interceptor.

Again, the way we listen to an array is to know that the array has changed and we can update it accordingly

Because our goal is to know that the array has changed, we will just override the seven methods that can change the array, as follows

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)

const methodsToPatch = [
  'push'.'pop'.'shift'.'unshift'.'splice'.'sort'.'reverse'
]

/** * Intercept mutating methods and emit events */
methodsToPatch.forEach(function (method) {
  // cache original method
  const original = arrayProto[method]
  // Def is the object.defineProperty method that intercepts operations on arrays, such as arr.push
  // Now instead of using the method on the original prototype chain, use the mutator method below
  def(arrayMethods, method, function mutator (. args) {
  // This executes a primitive array method
    const result = original.apply(this, args)
    / / when the ob is observe, put the observer instance on the array value
    // So you can get observer in push method.
    const ob = this.__ob__
    // If the inserted element is an object type, the new element will be treated as a response
    let inserted
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    The observeArray method responds to the object elements of the array
    if (inserted) ob.observeArray(inserted)
    // notify change
    // This is the key to array responsiveness
    // Because the array method is executed, it will go here
    // Then we go to the deP update operation
    Update () --> queueWatcher() --> queueWatcher()
    ob.dep.notify()
    return result
  })
})
Copy the code

This is almost the basic content of the response type, just began to comb, there is a problem, but also please pass by the big guy criticism.

Here attach vUE source link vUE source