Vue 不能检测到对象属性的添加或删除
1、划重点了:Vue 不能检测到对象属性的添加或删除
官网——深入响应式原理(https://cn.vuejs.org/v2/guide...)中介绍到:受现代 JavaScript 的限制 (以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue 会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue 转换它,这样才能让它是响应的。
上面的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这种方法不能响应式更新视图层。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。