Vue中$set的使用

290 阅读1分钟

不使用$set添加数据属性

<template>
<div>
  <el-button @click="setMessage">添加属性</el-button>
  {{student.name}}
  <el-input v-model="student.age" size="small" :style="{width: '80px'}"></el-input>
</div>
</template>

<script>
export default {
name: "$set-test",
  data(){
   return {
     student:{
       name:'张三'
     }
   }
  },
  methods:{
    setMessage(){
      this.student.age=15
      console.log(this.student)
    }
  }
}
</script>

<style scoped>

</style>

image.png

点击添加属性,student对象已经添加了age属性,视图并没有实时更新

由于受JavaScript的限制,vue.js不能监听对象属性的添加和删除,因为在vue2.x版本中组件初始化的过程中,Object.defineProptery会为当前对象绑定属性,会调用getter和setter方法,监听对象属性的变化,所以该属性必须是存在在data中,视图层才会响应该数据的变化

## 使用$set更新数据

<template>
<div>
  <el-button @click="setMessage">添加属性</el-button>
  <p>{{student.name}}</p>
  <el-input v-model="student.age" size="small" :style="{width: '80px'}"></el-input>
  <br>
  <el-button @click="setArray">修改数组</el-button>
  <p>数组arr0:{{arr0}}</p>
  <p>数组arr1:{{arr1}}</p>
  <p>数组arr2:{{arr2}}</p>
</div>
</template>

<script>
export default {
name: "$set-test",
  data(){
   return {
     student:{
       name:'张三'
     },
     arr:['666','888','9999'],
     arr0:['foo','bar','baz'],
     arr1:['foo','bar','baz'],
     arr2:['a','b','c']
   }
  },
  methods:{
    setArray(){
      this.arr0[0]='zzz'  // Vue 不能检测以下变动的数组变化,改变元素视图不会更新 所以如果在实例创建后添加新的属性到实例上,则不会触发更新。
                          // 控制台可以看到元素已经改变  数组arr0:[ "foo", "bar", "baz" ]
    },
    setMessage(){
    // Vue.set(obj,key,value) 或 this.$set(obj,key,value)
      // 方式一:解决视图不更新问题,通过拷贝对象重新赋值
       this.student.age=15
       this.student=Object.assign({},this.student)
      // 方式二:解决视图不更新问题
    //  this.$set(this.student,'age',15)
      console.log(this.student)
      for (let i=1;i<this.arr.length;i++){
        console.log(i) // 1 2
        console.log(this.$set(this.arr,i,[]))
        this.$set(this.arr,i,[]) //更新数组除下标为0外的元素值为[] ,最终结果:[ "666", [], [] ]
      }
    //  现在有两个数组,分别为arr1,arr2,如果arr1以下标赋值改变数组,arr2以$set改变数组,结果是什么样呢?
      this.$set(this.arr1,1,'cc')
       this.arr2[0]='zzz'
     // 两个数组的值都更新了,也就是说,arr1用$set()方法更新时,页面会全部更新一遍。
    }
  }
}
</script>

<style scoped>

</style>

image.png