Vue 不能检测到对象属性的添加或删除

1、划重点了:Vue 不能检测到对象属性的添加或删除

官网——深入响应式原理(https://cn.vuejs.org/v2/guide...)中介绍到:受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。

var vm=new Vue({

      data:{

            a:1

      }

})

//   'vm.a'是响应的

//   ‘vm.b’是非响应的

上面的a是响应式的,所以a的改变后会自动渲染页面;
但是b是在vm实例创建之后添加的属性,所以他不是响应式的,当我们改变b的值的时候,通过DevTool看到的数据并不会改变,除非我们在DevTool中刷新数据,而且页面也不会刷新。

有三种解决方案:

var vm = new Vue{
    el: "#app",
    data:{
        obj:{
            name: "aaa"            
        }
    }
}

1、方案一:利用Vue.set(object,key,value)


Vue.set(vm.obj,"sex","man")

2、方案二:利用this.$set(this.object,key,value)

this.$set(this.obj,"sex","man")

3、方案三:利用Object.assign({},this.obj)

this.obj.sex = "man";
this.obj = Object.assign({},this.obj)

//或者下面方式

this.obj = Object.assign({},this.obj,{"sex","man"})

DEMO实例:


<template>
  <div class="parent">
    <h1 v-show="mainData.test.boolean">{{msg}}</h1>
    <button @click="getData">数据</button>
    <select name="" id="" @change="selectChange">
      <option value="001">上海</option>
      <option value="002">北京</option>
      <option value="003">天津</option>
    </select>
    <ul>
      <li v-for="(item,index) in list" :key="index" v-show="index < 10">
        <span class="red">{{item.id}}</span>
        <strong class="blue">{{item.title}}</strong>
      </li>
    </ul>
  </div>
</template>
<script>
export default {
  name: "Parent",
  data() {
    return {
      count: 10,
      size: 1024,
      mainData: {
        test: {
          aa: 12
        }
      },
      msg: "这是测试信息",
      list: []
    };
  },
  methods: {
    getData: function() {
      var self = this;
      this.$axios.get("http://jsonplaceholder.typicode.com/posts").then(rsp => {
        self.list = rsp.data;
        self.$set(self.mainData.test, "boolean", false);
      });
    },
    selectChange: function() {
      var self = this;
      self.$set(self.mainData.test, "boolean", true);
    }
  }
};
</script>
<style scoped>
ul li {
  border: 1px solid #ddd;
  margin-bottom: 10px;
  text-align: left;
}
.red {
  color: red;
}
.blue {
  color: blue;
}
</style>

实现的效果如下:(使用的方案二方法)

(1)、下拉框选项改变的时候,会显示“这是测试信息“文字
图片描述

(2)、点击”数据“按钮,获取数据,“这是测试信息“文字会隐藏
图片描述

2、划重点了:删除vue实例的属性

注意:Vue 不允许在已经创建的实例上动态添加新的根级响应式属性(root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上。

对于上述Demo实例中通过this.$set添加的属性,通过以下方式删除即可:

//以下这种方式可以删除属性,同时会触发数据响应式的更新


this.$delete(this.mainData.test, "boolean");

//而通过delete this.mainData.test.boolean这种方法不能响应式更新视图层。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue遍历给对象添加属性时,需要注意以下几点。 首先,由于Vue在初始化实例时会执行getter/setter转化过程,因此要让属性是响应式的,必须在data对象上已经存在。Vue不能检测对象属性添加删除,所以需要在data对象上预先定义好属性。 其次,Vue不允许在已经创建的实例上动态添加新的根级响应式属性。但是可以使用Vue.set(object, key, value)或this.$set(object, key, value)方法将响应属性添加到嵌套的对象上。例如,可以使用Vue.set(vm.obj, 'e', 0)或this.$set(this.obj, 'e', 0)来添加属性。此外,this.$set方法是全局Vue.set方法的别名。 另外,当你将一个普通的JavaScript对象作为data选项传入Vue实例时,Vue会遍历该对象的所有属性,并使用Object.defineProperty()将这些属性转化为getter/setter,实现对data的监听。这样一旦data发生改变,就会刷新视图。所以,需要将要添加属性定义在data对象中。 如果想向已有对象添加属性,可以使用Object.assign()或_.extend()方法。但是,添加对象上的新属性不会触发更新。为了解决这个问题,可以创建一个新的对象,包含原对象属性和新的属性,然后将新对象赋值给原对象。例如,可以使用Object.assign({}, this.obj, { a: 1, e: 2 })或this.obj = Object.assign({}, this.obj, { a: 1, e: 2 })来添加属性。<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值