背景:使用JSON.parse(JSON.stringify)或lodash的_.cloneDeep方法深拷贝一个Array数据constantForm,又利用constantForm创建了一个新数据showForm,在改变showForm时,拷贝的数据constantForm也会随着一起变
原因:因为constantForm的对象属性也存在引用类型(对象或数组),这些属性在constantForm创建后又被修改(比如直接修改了某个对象或数组的内部状态),这种修改可能会影响showForm的表现。因为showForm中持有对某个对象的引用(比如defaultValue),而这个对象在constantForm中也被引用。filter方法返回一个新数组,其中包含的是原数组中符合条件的元素的浅拷贝(即数组是新的,但是数组中的对象引用仍然是相同的)
代码示例:
data() {
const defaultValue = {
one: '默认值1',
two: '默认值2',
}
const listArr = {
list1: [
...
],
list2: [
...
],
}
const defaultForm = [
{
type: 'checkbox',
value: defaultValue.one,
list: listArr.list1,
},
{
type: 'radio',
value: defaultValue.two,
list: listArr.list2,
},
]
return {
constantForm: JSON.parse(JSON.stringify(defaultForm)),
}
},
methods: {
edit() {
this.showForm = this.constantForm.filter(item => item.kind===fundTypeMap.common || value.includes(item.kind))
}
}
解决方法:对数组中的每个对象进行深拷贝
edit() {
// JSON.parse(JSON.stringify())效率较低,因为对每个对象都进行了序列化和反序列化
this.showForm = this.constantForm.map(item => JSON.parse(JSON.stringify(item))).filter(item => item.kind===fundTypeMap.common || value.includes(item.kind))
// 可以使用lodash的cloneDeep,这种方法更灵活,可以处理更多类型的数据
this.showForm = this.constantForm.map(item => _.cloneDeep(item)).filter(item => item.kind===fundTypeMap.common || value.includes(item.kind))
}