根据vue的源码可知,vue会对data里面定义的对象一一递归进行数据监听与劫持,为每个属性都添加setter和getter方法,当监听到当前属性发生变化的时候,就调用这两个方法,从而实现双向绑定。那么未被定义的属性以及后续动态添加的属性,是不会被监听的,就会造成数据已发生变化,但视图没有更新的情况
而根据我们的编码习惯,我们通常会在打开弹窗的时候,对整个temp进行重新的赋值,而不是只对temp里面的某个属性单独做修改,那么举个例子
data(){
return {
temp:{name:'zhangsan',age:1}
}
}
//打开弹窗后,用当前row的表单数据整个替换this.temp
openEdit(row){
this.temp = row
}
假设我们getList的时候,获取到的当前行数据,只有{name:'zhangsan'}
而没有age属性,我们这时候把这行数据直接整个赋值给temp,那么temp里面也就没有了age属性,则后续再用this.temp.age=xxx就会发生数据已修改,但视图未更新的情况了。在vue看来,age属性算是后续动态添加的,是非响应式的,所以并未给该属性添加setter和getter方法。
如果想要解决这个问题,可以使用深浅拷贝的一些方法,比如解构赋值...,比如object.assign拷贝处理修改后再赋值,最常用的是直接使用vue官方提供的API指令Vue.set(obj,key,value)手动的把需要的属性变成响应式的,在代码中的使用如下所示。
注:obj:执行的对象,key:需要添加或修改的属性名,value:属性值。
this.$set(this.temp,'age',2)
此时age属性已变为响应式,数据的更新也会触发视图的更新了。