preface

Through the previous chapter, we know the Vue initialization data response principle, only shared how the object through defineReactive method to create monitoring data attributes, and the array is just slightly over, below we through the source code to get a look

Did not see the previous chapter Vue responsive principle, no matter, come, walk a wave of small gifts up Go Vue Object defineProperty

Observer Array section

First look back to the Observer class constructor SRC/core/Observer/index, js

// Let's go back to this code
 if (Array.isArray(value)) { / / array
      if (hasProto) {
        protoAugment(value, arrayMethods) // Rewrite the array prototype method
      } else {
        copyAugment(value, arrayMethods, arrayKeys) // Copy the existing methods of the array
      }
      this.observeArray(value) // Look deeply at each item in the array
    } else { 
      this.walk(value) // If it is an object, redefine the object type data (described in the previous chapter).}}Copy the code

protoAugment

The protoAugment method overwrites the array prototype method and points the prototype rewrite to arrayMethods

function protoAugment (target, src: Object) {
  target.__proto__ = src
}
Copy the code

observeArray

The observeArray method iterates through the array and calls an observer to see if it has been listened on. If it has not been listened on, the new Observer class creates a listener, as described earlier

  // If it is an array, iterate over the array and go to the observer method to see if it is listening
  observeArray (items: Array<any>) { 
    for (let i = 0, l = items.length; i < l; i++) {
      observe(items[i])  // Observe each item in the array}}Copy the code

Implement the array listener core

The js file content is not much, mainly to do a few things the SRC/core/observer/array. Js

  • Create array prototype, assign toarrayMethods
  • Override the array prototype method toarrayMethodsAnd modify this
  • The method entity looks up 10 rows as it recursively iterates over the changed array dataobserveArray
  • Notifying Wachter to update the view
import { def } from '.. /util/index'

const arrayProto = Array.prototype
// Create an array prototype and assign it to arrayMethods
export const arrayMethods = Object.create(arrayProto) 

const methodsToPatch = [ // The array is often modified
  'push'.'pop'.'shift'.'unshift'.'splice'.'sort'.'reverse'
]

/** * Intercept mutating methods and emit events */
methodsToPatch.forEach(function (method) {
  // cache original method
  const original = arrayProto[method]
  // Rewrite the array prototype
  def(arrayMethods, method, function mutator (. args) { 
    const result = original.apply(this, args) / / change this
    const ob = this.__ob__
    let inserted
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    // Observe the newly inserted data again
    if (inserted) ob.observeArray(inserted) 
    // Notify view updates
    ob.dep.notify()  
    return result
  })
})

Copy the code

conclusion

Vue rewrites the prototype chain by hijacking the array in data. Points to the array prototype method you define so that you can notify dependencies of updates when the array API is called. If the array contains a reference type; Reference types in the array are monitored again.

A link to the

  • Front-end visualization platform implementation scheme
  • Vue3 10 minutes takes you seconds to vue3
  • Vue template compilation principle
  • The vue constructor extends
  • How does VUEX state management work
  • Vue-router source analysis principle
  • Vue [how to listen for array changes]
  • Handwritten Vue response [object.defineProperty]
  • Vue responsive source sharing