通过按钮复制的模块,如何避免父子组件数据相互影响,如图,普通平开门单门衣柜这个位置,是通过popup弹出的左右联动的动态数据,每点击一次添加按钮,都会动态复制一份forms组件内容,现在的问题是,无论修改第一组或者第二组的红色字体位置数据,另外一个就会跟着变成同样的数据,请教如何做到他们不相同可以独立操作数据?
<template>
<view>
<uni-forms v-for="(item,index) in sku" :key="index">
<view class="items">
<view>{{item.title}}</view>
<view v-if="sku.length > 1" @click="deleteSku(index)">删除</view>
</view>
<view>
<view>
<view class="box-body" @click="toggle('bottom')">
<view>{{it2}}->{{it3}}</view>
</view>
<view>
<uni-popup class="pop" ref="popup" @change="change">
<view class="popup-content"
:class="{ 'popup-height': type === 'left' || type === 'right' }">
<view class="content1">
<view class="left">
<scroll-view :scroll-y="true" :scroll-with-animation="true"
:scroll-into-view="clickToId" :style="{'height':windowHeight}">
<view v-for="(v,i) in sortarr" :key="i" v-if="v.grade1 === name">
<view v-for="(item,i) in v.grade2" :key="i" @click="sg2(''+item.name)">
<view :class="['title',{active:i===currentNum}]" :id="'to'+i"
@click="setId(i)">
{{item.name}}
</view>
</view>
</view>
</scroll-view>
</view>
<view class="right">
<scroll-view :scroll-into-view="clickId" @scroll="scroll"
:scroll-with-animation="true" :scroll-y="true"
:style="{'height':windowHeight}">
<view v-for="(v,i) in sortarr" :key="i" v-if="v.grade1 === name">
<view v-for="(item,i) in v.grade2" :key="i">
<view class="title1,right_title" :id="'po'+i">---{{item.name}}---
</view>
<view v-for="(item,j) in item.grade3" :key="j">
<text class="item"
@click="sg3(''+item.name)">{{item.name}}</text>
</view>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</uni-popup>
</view>
</view>
</view>
<view>
<uni-file-picker limit="5"></uni-file-picker>
</view>
</uni-forms>
<view>
<button plain="true" @click="ad()">添加</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
name: {},
it3: "-",
it2: "-",
sku: [{
title: 1,
classify: {
it2: '-',
it3: '-'
},
image: []
}],
}
},
methods: {
ad() {
let number = this.sku[this.sku.length - 1].title;
number++;
const newsku = {
title: number,
classify: {},
image: []
};
this.sku.push(newsku);
},
},
}
</script>
避免父子组件数据相互影响,需要保证所复制的模块是独立的。在你的情况下,复制的模块是一个包含表单和弹出框的popup组件,因此可能存在多个组件使用相同的popup模块的情况。
为了解决这个问题,你可以对复制的popup组件进行独立化处理,即弹出框中表单子组件所使用的属性数据需要通过props属性传递到popup组件中,popup组件再将这些数据传递到表单组件中,保证这些数据只在当前的popup组件和它的子组件之间存在。这种方法也称为props的单向数据流,即从父组件向子组件传递数据,而子组件无法直接修改父组件的数据。
具体来说,你可以按照如下步骤操作:
修改复制的popup组件属性,将弹出框中表单子组件所使用的属性数据定义为组件的props属性。
在表单组件中,接收popup组件传递的props数据,并根据自身的props属性进行渲染和操作。注意在表单组件中不要直接修改父组件中的数据,而是通过自己的props属性进行操作。
通过这种方式,你可以确保每个popup组件都有自己的一份props属性数据,保证数据的独立性。当需要修改数据时,只会影响当前组件,而不会影响其他组件,解决了你现在遇到的问题。
不知道你这个问题是否已经解决, 如果还没有解决的话:回答:
这个问题可以通过使用深拷贝来解决。深拷贝是一种将对象从源对象完全复制到新对象的方法,这将独立地创建一个新的对象,与原始对象没有联系。这样就可以在子组件中赋值给新对象,以避免父子组件数据相互影响。
具体步骤如下:
import _ from 'lodash'
...
let obj = { a: { b: 2 } };
let copy = _.cloneDeep(obj);
console.log(copy); // { a: { b: 2 } }
console.log(copy === obj); // false
...
import _ from 'lodash'
...
methods: {
copyForm() {
let newData = _.cloneDeep(this.form.data);
// 这里使用Vue.set方法向对应的数组中添加元素,而不是直接使用push方法
// 以保证新添加的元素也能够被Vue所监听
this.$set(this.forms, this.forms.length, { data: newData });
}
}
...
这样,每次复制的时候就会创建一个新的对象,与原始对象没有关系,即使修改其中一个对象的数据也不会影响到其他对象。