vue中循环表格数据,出现数据联动现象。
问题描述:如图
我输入期数为4,会循环出来4个表格,其中名额分配一栏人数是可以编辑的,但是当我修改第一个表格的数据之后,后面的表格数据也跟着修改了。
源码如下
<template><div class="content"><div style="margin: 20px;"><span>期数:</span><el-input-number v-model="periods" :min="0" size="small" :precision="0" :controls="false" @change="handleChange"/></div><div v-for="(tableData, index) in listDatas" :key="index" style="margin-top: 20px;"><div style="width: 100%; text-align: right; margin-bottom: 5px;"><el-button type="primary" size="small" plain @click="rowDel(index)">删除</el-button></div><vxe-table:data="tableData"borderstripesize="mini"><vxe-column align="center" field="sectionDeptName" title="站段" min-width="180"></vxe-column><vxe-column align="center" field="userNumber" title="分配名额" min-width="180"><template #default="{ row }"><el-input-number v-model="row.userNumber" :min="0" size="small" :precision="0" :controls="false"/></template></vxe-column></vxe-table></div></div>
</template><script setup>
import { ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';// 期数
const periods = ref(0);
// 表格数据列表
const listDatas = ref([]);// 初始表格数据
const initialData = [{ sectionDeptName: '初中', userNumber: 100 },{ sectionDeptName: '高中', userNumber: 50 },{ sectionDeptName: '小学', userNumber: 60 },{ sectionDeptName: '大学', userNumber: 30 }
];// 期数变化处理
const handleChange = (e) => {if (listDatas.value.length === 0) {for (let i = 0; i < e; i++) {listDatas.value.push(initialData);}} else {let i = listDatas.value.length;for (i; i < e; i++) {listDatas.value.push(initialData);}}
};// 行删除事件
const rowDel = (index) => {ElMessageBox.confirm('确定将选择数据删除?', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {listDatas.value.splice(index, 1);}).then(() => {ElMessage({type: 'success',message: '操作成功!'});});
};
</script><style scoped>
.content {padding: 20px;
}
</style>
问题原因
你遇到的问题是因为在生成多个表格时,所有表格的数据都引用了同一个对象或数组,导致数据联动现象。要解决这个问题,你需要确保每个表格的数据是独立的副本,而不是引用同一个对象或数组。
解决方案
在生成表格数据时,使用深拷贝来确保每个表格的数据是独立的副本。
代码如下
<template><div class="content"><div style="margin: 20px;"><span>期数:</span><el-input-number v-model="periods" :min="0" size="small" :precision="0" :controls="false" @change="handleChange"/></div><div v-for="(tableData, index) in listDatas" :key="index" style="margin-top: 20px;"><div style="width: 100%; text-align: right; margin-bottom: 5px;"><el-button type="primary" size="small" plain @click="rowDel(index)">删除</el-button></div><vxe-table:data="tableData"borderstripesize="mini"><vxe-column align="center" field="sectionDeptName" title="站段" min-width="180"></vxe-column><vxe-column align="center" field="userNumber" title="分配名额" min-width="180"><template #default="{ row }"><el-input-number v-model="row.userNumber" :min="0" size="small" :precision="0" :controls="false"/></template></vxe-column></vxe-table></div></div>
</template><script setup>
import { ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';// 期数
const periods = ref(0);
// 表格数据列表
const listDatas = ref([]);// 初始表格数据
const initialData = [{ sectionDeptName: '初中', userNumber: 100 },{ sectionDeptName: '高中', userNumber: 50 },{ sectionDeptName: '小学', userNumber: 60 },{ sectionDeptName: '大学', userNumber: 30 }
];// 期数变化处理
const handleChange = (e) => {if (listDatas.value.length === 0) {for (let i = 0; i < e; i++) {let tableData = initialData.map(item => ({ ...item})); // 使用深拷贝listDatas.value.push(tableData);}} else {let i = listDatas.value.length;for (i; i < e; i++) {let tableData = initialData.map(item => ({ ...item})); // 使用深拷贝listDatas.value.push(tableData);}}
};// 行删除事件
const rowDel = (index) => {ElMessageBox.confirm('确定将选择数据删除?', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).then(() => {listDatas.value.splice(index, 1);}).then(() => {ElMessage({type: 'success',message: '操作成功!'});});
};
</script><style scoped>
.content {padding: 20px;
}
</style>