scenario

Sometimes we see code like this:



As we develop with vUE, we may encounter situations where, after generating a VUE instance, when assigning a value to an object again, it is not automatically updated to the view; When we look at the VUE documentation, we will find this sentence:If new properties are added to the instance after it is created, it does not trigger view updates.Add the age property to the student object.

data () {
  return {
    student: {
      name: ' ',
      sex: ' '
    }
  }
}
mounted () { // -- the hook function after the instance is mounted
  this.student.age = 24
}
Copy the code

Restricted by ES5, vue.js cannot detect the addition or deletion of object attributes, that is, Vue does not check for dirty data. Because vue.js converts a property to a getter/setter when initializing an instance, the property must be on the data object for vue.js to transform it in order for it to be responsive. $set(this.data, “key”,value’) $set(this.data, “key”,value’)

mounted () {
  this.$set(this.student,"age".24)}Copy the code

Vue does not allow you to dynamically add root-level reactive properties.

Such as:

const app = new Vue({
  data: {
    a: 1
  }
  // render: h => h(Suduko)
}).$mount('#app1')

Vue.set(app.data, 'b'.2)
Copy the code

The console returns an error:



Available onlyVue.set(object, propertyName, value)Method to add reactive properties to a nested object, for example

var vm=new Vue({
    el:'#test',
    data:{
        // The info root attribute already exists in data
        info:{
            name:'Ming'; }}});// Add a gender attribute to info
Vue.set(vm.info,'sex'.'male');
Copy the code

Vue. Set () : how does this.$set() relate to vue.set?

Vue. Set () and this.$set()

Vue. Set () ¶

import { set } from '.. /observer/index'. Vue.set = set ...Copy the code

$set() this.$set()

import { set } from '.. /observer/index'. Vue.prototype.$set = set ...Copy the code

Vue. Set () and this.$set() use the same set function. The set function is derived from… Set () binds the set function to the Vue constructor. This. $set() binds the set function to the Vue prototype.

Set:

function set (target: Array<any> | Object, key: any, val: any): any {
  if(process.env.NODE_ENV ! = ='production' &&
    (isUndef(target) || isPrimitive(target))
  ) {
    warn(`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`)
  }
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key)
    target.splice(key, 1, val)
    return val
  }
  if(key in target && ! (key in Object.prototype)) { target[key] = valreturn val
  }
  const ob = (target: any).__ob__
  if (target._isVue || (ob && ob.vmCount)) { process.env.NODE_ENV ! = ='production' && warn(
      'Avoid adding reactive properties to a Vue instance or its root $data ' +
      'at runtime - declare it upfront in the data option.'
    )
    return val
  }
  if(! ob) { target[key] = valreturn val
  }
  defineReactive(ob.value, key, val)
  ob.dep.notify()
  return val
}
Copy the code

The set function takes three parameters: target, key, and val. The value of target is an array or an object.

Develop reading

  • Vue Advances (97) : Vue dynamically adds properties and values to objects