As we develop with vUE, we may encounter situations where, after generating a VUE instance, the data is not automatically updated to the view when it is assigned again. When we look at the VUE documentation, we will see that if new attributes are added to the instance after it is created, it will not trigger view updates. Add the age property to the student object

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

Restricted by ES5, vue.js cannot detect additions or deletions of object attributes. 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 dynamic addition of root-level reactive attributes.

Such as:

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

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

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

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
As a result we find vue.set () and this.$set() The implementation principle of these two apis is basically the same, both are usedsetFunction.setFunction from.. /observer/index file, the difference is that Vue. Set () will besetThe function is bound to the Vue constructor, this.$set() issetThe function is bound to the Vue prototype.Copy the code
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 intarget && ! (keyin Object.prototype)) {
    target[key] = val
    return 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.

Reference:

Pit encountered in VUE — Change detection problem (Array related)