el-table实现表格分页多选

1,001 阅读3分钟

在elementUI中,默认的选择分页之后再切回来不会显示之前的选择。最近接到了一个需求就是可以分页选择,切换回原来的页数可以回显,并且支持导出所选择的数据。 首先我们需要考虑一个问题就是el-table中选择时只会记录当前表格中的数据的选中状态,刷新页面后,此时表格中的数据发生了变化,选中状态又会重新计算,因此每次切换页面或者修改 页面显示的条数,表格中的选择状态都会显示刚开始还没有选中的状态。

具体实现思路:

  1. 创建一个全局变量selectedMap用来存总的选中数据,每个页面选中的数据都存到这个变量中,我们用map来存这个变量是map中的key只能唯一,保证数据的唯一性。 const selectedMap = new Map();

  2. 在触发选中数据的函数中建一个map类型变量currSelectMap用来存储当前页面中的选中数据,创建另外一个数组类型变量selectList用来存储有过选择的数据,(这里解释一下为什么要存两个变量来存储当前选择的数据情况, 因为currSelectMap是用来记录选中的,selectList是用来记录曾经选过的,只要你选中过,不管你后来有没有取消选择,这个数组里面都会有,只是它的选择属性会随着变,这个变量就是为了存储选中数据的前后属性变化的). 然后遍历selectList数组,如果selectedMap中但是selectList中这个数据的selected属性为false, 则说明这个数据被选择后又被取消了,因此需要将它从selectedMap中删除。

  // data2 表示当前勾选项,属于array类型
  // 我们首选需要一个list用来记录当前listData都有哪些备选哪些没有被选上,我这里先用一个map记录当前表格中的备选项
  // 然后遍历listData 把已选项维护到一个list中
  const currSelectMap = new Map();
  for (let i = 0; i < data2.length; i++) {
    currSelectMap.set(data2[i].applyDate, true);
  }

  const selectList = [];
  this.listData.forEach((item) => {
    const applyDate = item.applyDate;
    selectList.push({
      applyDate,
      selected: currSelectMap.has(applyDate) ? true : false,
    });
  });
// 遍历selectList,它记录了当前表格中每一项的一个唯一ID(我这里是applyDate是唯一的),以及是否选中两个参数
// 遍历过程中与记录总的被选中的数据做一个比较,代码由本文前面的处理逻辑形成
  selectList.forEach((item) => {
    const applyDate = item.applyDate;
    const selected = item.selected;
    if (selectedMap.has(applyDate) && !selected) {
      selectedMap.delete(applyDate);
    }
    if (!selectedMap.has(applyDate) && item.selected) {
      selectedMap.set(applyDate, item);
    }
  });

  1. 在分页,或者页面条数变化的监听函数中遍历数据,如果selectedMap中有这个数据,说明数据被选中了, 需要将选中状态在el-table组件中渲染出来。 其中toggleRowSelection是用于多选表格,切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否(selected 为 true 则选中)
 for (let i = 0; i < this.listData.length; i++) {
  //如果有的话,添加进去,把参数设置为true
  const applyDate = this.listData[i].applyDate;
  if (selectedMap.has(applyDate)) {
    this.$nextTick(() => {
      this.$refs.mainTable.$children[0].toggleRowSelection(this.listData[i], true);
    });
  }
}

额外说明:

  1. 我在调用toggleRowSelection方法的时候本来的代码是这样写的:
    this.$refs.mainTable.toggleRowSelection(this.listData[i], true);

但是浏览器一直提示toggleRowSelection is not a function。 ddc0ce20-8adc-4987-8800-edde18f35c6c.png

我打印了this.refs.mainTable的内容,里面确实没有toggleRowSelection这个方法,后来我在this.refs.mainTable的内容,里面确实没有toggleRowSelection这个方法,后来我在this.refs.mainTable.$children里找到了toggleRowSelection 方法。 428e7792-6cd2-40ac-925a-07b6b82b069c.png 是因为:我在这里引用的表格组件是封装好的组件,在封装好的组件里面才有真正的el-table标签,因此需要去它的子元素中获取。

  1. 在页面中勾选数据的时候,我只要一勾选数据,表格头部的全选按钮显示的样式是全选的样式,而不是非全选的样式。

0def9ae8-1c37-4d32-81fe-36e176111d05.png 经过查证,可以发现每次选中数据之后,添加的样式都是.is-checked,而不是.is-indeterminate,这个是是因为row-key不唯一,导致在添加样式的时候出现了问题。 因此需要将row-key设置为唯一的值就可以了。

447bd29b-1009-43f9-b634-46bd822657fb.png