不少需求都会有这个要求,不想做的时候就说做不了。
这次需求没注意,暗戳戳穿插了一个翻页记录勾选值的内容。
没办法一言以蔽之,要求的效果如下图:
那就记录一下两种实现方法。
① 用一个数组记录选中的行id tbSelIds: [selIds]
② 用MAP记录每页选中的行id,键值对tbSelIdMap: { pageNo: [selIds] }
单个数组记录
实现思路
把选中的行数据id都记录起来存到tbSelIds中;翻页的时候,比对当前页数据id是存在tbSelIds中,是就勾选起来。
用一个数组存,可以解决测试小朋友说的·这个搜索完怎么没有勾上呀;这个怎么修改一页几条,没有勾上呀;这个错乱不好的吧·
听到这些真想脸滚键盘。
需要处理的场景:
① 左侧表格,选中复选框,记录选中的id
② 左侧表格,去掉勾选复选框,去掉选中的id
③ 输入搜索条件/切换页码/切换分页条数,搜索后,将页码中被勾选过的值,自动勾上
④ 右侧表格移除选项,自动从左侧表格中去掉勾选。
看,多简单,处理完这四个就好。
遇到的问题
- el-table表格,勾选、去掉勾选,
@selection-change方法回调的参数值是,当前页选中的所有行。它没有回调谁被删除了 :) --- 解决方法,当前页选中的,对比已选值,中间的差值,就是去掉勾选的。 - el-table表格将表格选上的方法只有两种,全选
toggleAllSelection和勾选某一个toggleRowSelection:) --- 但是好恶熏,多个要自动勾上的值,一个一个勾上的时候,就和1↑冲突了。没选的被当做删了,所以加了一个waitSelIds等待选中的值,综合判断。 - 切换页码的时候,会自动清空所有选项 :)
贴贴代码
选中复选框
/**
* 选中复选框
*/
handleSelectionChange(vals) {
// 校验是不是isSearch,是则return,因为搜索的时候,会清空所有选项
if (this.isSearch && vals.length === 0) {
this.isSearch = false
return
}
this.isSearch = false
// waitSelIds是为了解决上述的问题2
const { tableData, waitSelIds } = this
const selIds = vals.map(item => item.id)
const optIds = this.optList.map((item) => item.id);
// 当前页面没选中的行id
const unSelIds = tableData.filter(i => !selIds.includes(i.id)).map(item => item.id)
const filterUnSelIds = _difference(unSelIds, waitSelIds);
if (_intersection(waitSelIds, unSelIds).length === 0 ) {
this.waitSelIds = []
}
// 未选中的id中,且出现在optList中的id,是被删除的
const delIds = optIds.filter(i => filterUnSelIds.includes
(i))
// 右侧表格所有的数据id, optIds
const addIds = _difference(selIds, optIds);
// 遍历需要删除的id数组,从表格B的数据中移除对应的数据
delIds.forEach((id) => {
const index = this.optList.findIndex((item) => item.id === id);
if (index !== -1) {
this.optList.splice(index, 1);
}
});
// 遍历需要新增的id数组,从表格A的数据中查找对应的数据,并添加到表格B的数据中
addIds.forEach((id) => {
const item = this.tableData.find((item) => item.id === id);
if (item) {
this.optList.push(item);
}
});
// 更新一次目前选中的ids
this.tbSelIds = this.optList.map((item) => item.id);
},
移除右侧表格B的内容,左侧表格去掉勾选
/**
* 移除右侧表格B中的内容
*/
handleRemoveRightRow(rows) {
const deleteIds = rows.map(item => item.id)
// 遍历需要删除的id数组,从表格B的数据中移除对应的数据
// 并且在取消左侧表格勾选和tbSelIdMap中的数据
deleteIds.forEach((id) => {
const index = this.optList.findIndex((item) => item.id === id);
if (index !== -1) {
this.optList.splice(index, 1);
}
});
this.tbSelIds = this.optList.map(item => item.id)
// 把左侧表格中,与被移除的id相同的行,去掉勾选
this.triggerTbSelection(deleteIds, false)
}
搜索后,重新勾选已选中的值
reCheckTable() {
const { tbSelIds } = this
const currentIds = this.tableData.map((item) => item.id);
const selIds = currentIds.filter((ele) => tbSelIds.includes(ele));
if (!selIds || selIds.length <= 0) return
this.triggerTbSelection(selIds, true)
},
勾选、反勾选表格
triggerTbSelection(aimIds, val) {
this.waitSelIds = val? aimIds: []
this.tableData.forEach(row => {
if (aimIds.includes(row.id)) {
this.$refs?.multipleTable.toggleRowSelection(row, val)
}
})
},
MAP记录
如果有输入搜索条件/切换分页条数。不建议用MAPtbSelIdMap: { pageNo: [selIds] },搜索完后,每页展示的内容就不同了,这种按页记录选中id的话,就很不好处理。
这部分和上面差不多,优点是,需要的循环和遍历比较少,上面的遍历太多辣。
代码不想贴了,结束。
插个题外话:疫情开放以来,裁员的新闻屡见不鲜。很多朋友说,需早谋出路。35失业如何如何,失业了开滴滴、跑外卖。不如趁早规划。说的都对,但还是不要焦虑,脚踏实地做好每件事。
「悲观者永远正确,乐观者永远前行」