在开发过程中,我们时常会遇到这样一种情况:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的。
这是为什么呢?
让我们来看官方文档是怎么写的:
受现代 JavaScript 的限制(以及废弃 Object.observe),Vue 不能检测到对象属性的添加或删除。由于 Vue会在初始化实例时对属性执行 getter/setter 转化过程,所以属性必须在 data 对象上存在才能让 Vue
转换它,这样才能让它是响应的。例如:
<template>
<div>
<p @click="addValueA(obj)"> {{obj['valueA']}} </p>
<p @click="addValueB(obj)"> {{obj['valueB']}} </p>
</div>
</template>
<script>
export default {
data(){
return {
obj: {valueA: 0},
}
},
created() {
this.obj['valueB'] = 0;
console.log(this.obj);
},
methods: {
addValueA(obj) {
obj.valueA = obj.valueA + 1;
console.log('valueA--' + obj.valueA);
},
addValueB(obj) {
obj.valueB = obj.valueB + 1;
console.log('valueB--' + obj.valueB );
}
}
}
</script>
<style scoped>
</style>
我们首先在浏览器中查看console.log(this.obj);
这句话的打印结果:
可以看出ValueA属性是有get 和 set方法的,而新增的ValueB属性是没有的。
让我们来触发三次增加ValueA的函数,网页打印结果如下:
同时页面上的显示情况:
我们继续触发三次增加ValueB的函数,网页打印结果如下:
同时页面上的显示情况:
由此看出,更新ValueA时,数据与视图会同步更新,而更新ValueB的时候数据会被更新而视图却不会被更新
解决方案:
官方定义:
Vue 不允许在已经创建的实例上动态添加新的根级响应式属性 (root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将响应属性添加到嵌套的对象上:
Vue.set(data.obj, 'key', value)
您还可以使用 vm.$set 实例方法,这也是全局 Vue.set 方法的别名:
this.$set(this.obj,'e',02)
上述实例解决如下:
//将created()钩子函数修改如下
created() {
this.$set(this.obj,'valueB',0);
console.log(this.obj);
},
重新运行可以看出ValueA和ValueB都有了get与set方法
再分别触发增加ValueA和ValueB的函数,视图与数据都进行了更新:
网友评论