问题
今天遇到了一个很诡异的问题,已经有近 3 个月事件没有去动过的模块,突然就有 bug 了???咱也不知道是 why,总之情况就是这么一个情况:
1、一个新增表单,原先打开一切正常,字段也都可以填写。
2、一旦搜索项目,从远程获取回来数据,初始化好表单,就会发现,所有字段都无法填了。
我是这么给我的表单赋初始值的:
this.dialogformData = Object.assign({}, this.dialogformData, data)
奔着想要保留 dialogformData 的原始响应性,并且只是想要添加或更新一些属性,避免替换整个对象的想法,又尝试了一种做法:
this.dialogformData = { ...this.dialogformData, ...newData };
依然不行......
解决
最终的解决方案就是,通过 this.$set 的方式,将返回回来的字段全部挂到 formData 里面。
const keyList = Object.keys(data)
for (let i = 0; i < keyList.length; i++) {
this.$set(this.dialogformData, keyList[i], JSON.parse(JSON.stringify(data[keyList[i]])))
}
原因
当用 this.dialogformData = Object.assign({}, this.dialogformData, data) 来更新 dialogformData 时,实际上是创建了一个新的对象,这个新对象包含了 this.dialogformData 和 data 的所有属性,但是丢失了原始 dialogformData 对象的响应性。
在Vue中,当直接替换一个响应式对象的引用时(即使新对象包含相同的属性),Vue不会跟踪这个新对象的属性变化,因为 Vue 的响应式系统是基于原始对象的 getter 和 setter 的。
为了解决这个问题,应该只更新 dialogformData 的属性,而不是替换整个对象。
存疑
其实,我还是很疑惑,咋从来没动过的模版,会突然出现这种问题呢?项目中其它模块也都是使用了这种方式去给表单做初始化,但是目前却没有这样的问题。。。。我真的不理解