The introduction

I read vue.js document for many times, but I still don’t understand some knowledge points. Then there is the plan to reread the vue.js document. This Vue array update analysis and combined with the source code, I hope to help you.

Mutation method

Mutating methods, as the name suggests, changes the original array in which those methods were called. Since arrays are references, the address stored in stack memory does not change, but the actual array value. Include:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
const arr = arr1 = [1.2.3];
arr === arr1; // true arr === arr1 == [1, 2, 3];
arr.push(4);
arr === arr1; // true arr === arr1 == [1, 2, 3, 4]; The value of the array has changed, but the two arrays still point to the same address
Copy the code

Non-mutation method

That is, the array from which these methods are called does not change, but always returns a new array. For example: concat, filter, map, slice, etc. But with a non-mutating method, we can replace the old array with the new one.

new Vue({ data () { return { imgs: ['https://juejin.im/1', 'https://juejin.im/2', 'https://juejin.im/3', 'https://juejin.im/4', 'https://juejin.im/5'] } }, methods: { transform () { this.imgs = this.imgs.map(img => img + '.jpg'); // Replace the old array with the new array}}})Copy the code

An array of update

In both mutated and non-mutated arrays, the address pointer does not change when the array value changes. Vue is a data-driven framework, and when array values change, it’s natural to expect views that depend on changing data to trigger updates as well. As anyone who has used VUE knows, when an array changes, the view is updated. So what does VUE do for us? Let’s take a look at the source code.

/ / the vue 2.6
// src/core/observer/array.js
const arrayProto = Array.prototype; // Get the array prototype object
const arrayMethods = Object.create(arrayProto); // Generate a new object with __proto__ pointing to the array prototype object
const methods = ['push'.'pop'.'shift'.'unshift'.'splice'.'sort'.'reverse'];

/** * Intercept mutating methods and emit events */
methods.forEach(method= > {
    const original = arrayProto[method]; 
    let val = function mutator (. args) {
        const result = original.apply(this, args); // Cache the original method
        let inserted = null;
        switch (method) {
            case 'push':
                inserted = args;
                break;
            case 'unshift':
                inserted = args;
                break;
            case 'splice':
                inserted = args.slice(2); // array.splice(start[, deleteCount[, item1[, item2[, ...]]]]) [item])
                break;
        }
        if (inserted) observeArray(inserted); // Gets the inserted value and sets reactive listening
        notify(); // The notification depends on the image update
        return result;
    }
    
    Object.defineProperty(arrayMethods, method, {
        value: val,
        writable: true.configurable: true.enumerable: true})})const observeArray = function observeArray (inserted) { / / short, concrete implementation (https://github.com/vuejs/vue/blob/2.6/src/core/observer/index.js)
    console.log(inserted); // The new element forms an array
    console.log('Responsive listening array');
}

const notify = function notify () {
    console.log('View updated');
}
Copy the code

Matters needing attention

Due to JavaScript limitations, Vue cannot detect changes to the following arrays:

  1. Set an array item directly using an index, for example:vm.imgs[index] = newValue
  2. To change the length of an array, for example:vm.imgs.length = newLength

To solve the first type of problem:

// Vue.set
Vue.set(vm.imgs, index, newValue);

// Array.prototype.splice
vm.imgs.splice(index, 1, newValue);
Copy the code

To solve the second problem:

vm.imgs.splice(newLength);
Copy the code

conclusion

The above is a personal understanding of the VUE array, I hope to help you. If there is a mistake or not rigorous place, welcome criticism and correction, if you like, welcome to praise.

reference

  • Vue document
  • Vue source 2.6
  • Array correlation method