Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

The role of $set

Vm.$set(target, key, value) accepts three parameters

  • The target value of targer
  • Key Specifies the property to be set
  • Value Indicates the value to be set

Values that were set when data was initialized can trigger view updates when we change their values, but new properties cannot be traced and trigger view updates. For example, in person:{name:’ three ‘} we want to add an age property. Setting the property by assigning is not reactive. So you need to set it with the $set method.

Preliminary preparation and materials

  • This article is based on vue2.6.14
  • Demo address portal (in order to facilitate the execution of the source code, please debug under the debugger view, in the demo key code has hit the Debugger)
  • Demo code

Interpretation of the

Front-end related code

<div id="app">
    <h2>Array handling</h2>
    <p v-for="num in numList">{{num}}</p>
    <button v-on:click="add">add</button>
    <h2>New attributes</h2>
    <p v-if="person.name">{{person.name}}</p>
    <p v-if="person.age">{{person.age}}</p>
    <button v-on:click="setAge">Add the age</button>
</div>
<script>
    let vue = new Vue({
        el: '#app'.data: {
            numList: [0.1].person: {name: 'Joe',}},methods: {add(){
                this.$set(this.numList, this.numList.length, this.numList.length)
            },
            setAge(){
                this.$set(this.person, 'age'.18)}}});</script>
Copy the code

The principle of $set is to add $set method on the prototype of VUE, and at the same time for the following three cases respectively

  • If a key already exists in the target, modify the value of the key in the target directly
  • When target is an array, the array is assigned by the splice method of vUE’s internal interception'push','pop','shift','unshift','splice','sort','reverse'Methods are intercepted as responsive, and calling these methods can trigger an update to the interface (explained in this section later) if only througharr[2]=2Does not trigger a view update.
  • For new attributes, define Active converts data into getters and setters and triggers data change notifications
function set (target, key, val) {
    if (isUndef(target) || isPrimitive(target)) {
      warn(("Cannot set passive properties on undefined, NULL, or primitive values"));
    }
    // Array processing
    if (Array.isArray(target) && isValidArrayIndex(key)) {
      target.length = Math.max(target.length, key);
      target.splice(key, 1, val);
      return val
    }
    // target already has a corresponding key
    if (key intarget && ! (keyin Object.prototype)) {
      target[key] = val;
      return val
    }
    // Handle the new attributes
    var ob = (target).__ob__;
    if (target._isVue || (ob && ob.vmCount)) {
      warn("Target cannot be an instance or root data object of a VUE");
      return val
    }
    if(! ob) { target[key] = val;return val
    }
    defineReactive$$1(ob.value, key, val);
    ob.dep.notify();
    return val
  }
  Vue.prototype.$set = set;
Copy the code

Below is the code execution for processing arrays

Below is the code execution for the new attribute handling