当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的。
问题出现的背景:
1:我需要做一个类似与多选框的效果
2:有一个all_list所有机型,后台会提供允许机型allow_list ,我需要根据允许机型来匹配页面选中的状态
3:想到的解决方法是,给对象添加新的 属性根据这个属性来判断状态
问题的出现:
更改了状态值后,打印出来的属性值是更改的,但是页面视图没有实时更新,举个例子
<template>
<div>
<p @click="addNuma(obj)">{{obj.a}}</p>
<p @click="addNume(obj)"> {{obj.e}}</p>
</div>
</template>
<script>
export default {
data(){
return {
obj:{}// 也可以定义数组
}
},
mounted() {
this.obj = {a: 0};
this.obj.e = 0;
console.log( this.obj);
},
methods: {
addNuma(item) {
item.d = item.d + 1;
console.log(item);
},
addNume(item) {
item.e = item.e + 1;
console.log(item);
}
}
}
</scirpt>
从打印值中我们可以看出 a 有get和set 方法,而e没有这个方法
此时,我们点击addNuma这个方法,发现,视图变成了1 ,打印值也是1,然后,点击addNume这个方法,发现视图没有改变,但是打印值却变成了1
更新新增属性e,是不会更新视图,但是会改变其值,当更新原有属性d时会更新视图,同时将新增的属性e的值也更新到视图里边
这就是问题的所在
解决方案
官方定义:如果在实例创建之后添加新的属性到实例上,它不会触发视图更新
有时你想向已有对象上添加一些属性,例如使用 Object.assign() 或 _.extend() 方法来添加属性。但是,添加到对象上的新属性不会触发更新。在这种情况下可以创建一个新的对象,让它包含原对象的属性和新的属性:
mounted(){
this.obj={a:0}
this.$set(this.obj,'e',0)
}
这样就解决了我们上面的问题
但是有时候我们更改的是数组,此时,我们可以这样写
数组===> this.$set( Array, index , value)
对象===>this.$set(Object,''key'',value)
好啦~今天就分享到这里吧,欢迎一起讨论,一起学习