不凡说 / 文章详情

【前端培训-知识点】VUE实现动态给对象或数组增加新属性

2022-04-22 16:50 2397

在开发过程中,我们时常会遇到这样一种情况:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的。

根据官方文档定义:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新。

举个例子:

这是一个vue组建,在created钩子函数中向person对象添加新属性,同时视图中多选框绑定了该属性,但是当更新数据或视图,对应的视图或数据并未更新

<template>
  <div class="home">
    {{ person.name }}<input type="checkbox" v-model="person.sex">
  </div>
</template>

<script>
export default {
 data(){
   return {
     person:{
       name:"张三"
     }
   }
 },
 created(){
   this.person.sex = 0
 }
}
</script>

原理

vue属于MVVM框架,数据操作视图。对data对象中的数据进行监听,当侦测到数据改变时相应数据所影响的页面也会触发更新。所以我们所需要的这些响应式数据,受到javascript的限制,vue不能检测到对象属性的添加或删除,因为Vue利用的是Object的defineProperty()方法,在初始化实列时将属性转为getter/setter,所以属性必须在data对象上才能让vue转换它。
当然这只是一般的属性,以一般字符串,数字,布尔值这样的基本数据类型作为属性值的响应,当然我们有时候的诉求的初始化属性的属性值不只有这样的基本数据变量,我们还会用到数组,对象这样的引用数据变量。

给对象添加新属性

<template>
  <div class="home">
    {{ person.name }}<input type="checkbox" v-model="person.sex"> {{ person.sex ? "男" : "女" }}
  </div>
</template>

<script>
export default {
 data(){
   return {
     person:{
       name:"张三"
     }
   }
 },
 created(){
  //  错误做法
  // this.person.sex = 0

  // 正确做法
  this.$set(this.person,"sex",0)
 }
}
</script>

给数组添加新属性

<template>
  <div class="home">
    <ul>
      <li v-for="item in cartList" :key="item.id">
        <label>
          {{ item.name }}
          <input v-model="item.isSelected" type="checkbox" >
        </label>
        
      </li>
    </ul>
  </div>
</template>

<script>
export default {
 data(){
   return {
     cartList:[
       {
         name:"苹果",
         id:1
       },
       {
         name:"香蕉",
         id:2
       },
       {
         name:"橘子",
         id:3
       },
     ]
   }
 },
 created(){
   //  错误代码
  //  this.cartList.forEach(ele =>{
  //    ele.isSelected = false
  //  })
  
  // 正确添加新属性
  this.cartList.forEach(ele =>{
     this.$set(ele,"isSelected",false)
   })
 }
}
</script>