一、问题描述:
表格数据是一次性从后端获取到了全部的数据(可前端假分页),在模糊检索表格数据时,因为el-table的数据源data发生了变化,重新触发了@selection-change事件,此时如果仅仅是在@selection-change事件对应的方法中对回显的选中项(获取到表格数据要回显的选中项目)进行赋值,会导致选中项被清空,无法保留之前的选中项。
二、解决历程:
我想大家的想法应该和我的差不多,对初始的选中项进行记录,随后再进行回显以及数据改变的处理逻辑,没错,我就是这样写的,但是它失败了,无论我在@selection-change事件的对应方法中写了多少处理逻辑,换了多少种处理方式,都始终绕不过data改变@selection-change触发而参数为空数组的这一个坎儿。至此一个小时已经过去了......
随后我思考了一个问题,在@selection-change处理函数中既然我没有办法对选中的数据进行处理,那么我可不可以在外边进行处理呢?实践得真知:
1、记录列表加载时表格数据的选中项(因为我的表格数据是一次性获取到的,也没有做分页,所以可以一次获取所有);
2、定义一个变量checkList来保存每次@selection-change触发时接受到的选中项参数,并且使用它来回显表格选中项;
3、startCheckList来作为基准值;
4、在提交和查询时对startCheckList结合进行checkList处理(重点)
第四点的处理逻辑:
(1)在当前展示的table数据中筛选出在checkList中的所有数据以及不在checkList中的所有数据,组成两个数组,分别为:tableSelectList和tableNoSelectList。
(2)判断tableSelectList中的数据是否在基准值startCheckList中?
如果在:则不做任何操作
如果不在:则将对应项push到startCheckList;
(3)判断tableNoSelectList中的数据是否在基准值startCheckList中?
如果在:则将对应的项从startCheckList中splice出来;
如果不在:则不做任何操作
(4)在处理完基准值startCheckList后,使用它对下一次表格筛选后进行回显。
三:代码片段
因为项目实际场景不同,主要还是参考以上第二点解决历程中的描述。所以仅贴上部分代码。
1、table
<el-table
ref="multipleTable"
:data="elementList"
border
height="600"
@selection-change="handleSelectionChange">
2、选中回显 (首次加载也要执行,就不码代码了)
// 进行选中。入参是行的那个对象
setDefaultSelection (rows) {
rows.forEach(row => {
this.$refs.multipleTable.toggleRowSelection(row);
});
},
3、首次加载获取已选中数据
// 页面初始获取选中数据
const checkList = elementList.filter(ele => {
if (insertIdList.indexOf(ele.id) > -1) {
return true;
} else {
return false;
}
});
// 如果通过深拷贝得到startCheckList,则会在对比中导致每一项对象始终与checkList中不同
// 采用浅拷贝,可以保证数组中每一项地址是相同的,则后续不需要去重操作
// this.startCheckList = JSON.parse(JSON.stringify(checkList));
this.startCheckList = [ ...checkList ];
this.setDefaultSelection(checkList);
this.checkList = checkList;
4、对startCheckList
// 选中项处理
handleCheckList () {
console.log(this.checkList);
this.elementList.forEach(item => {
// 如果elementList的项目在checkList中,不在startCheckList中则push
if (this.checkList.includes(item) && !this.startCheckList.includes(item)) {
this.startCheckList.push(item);
} else if (!this.checkList.includes(item) && this.startCheckList.includes(item)) {
this.startCheckList.splice(index, 1);
}
});
},
5、获取到新的data数据之后重新回显选中项
// 获取表格数据
// ......
this.$nextTick(()=>{
this.setDefaultSelection(this.startCheckList);
})