element UI 表格组件,记录翻页勾选的复选框并展示出来

191 阅读3分钟

不少需求都会有这个要求,不想做的时候就说做不了

这次需求没注意,暗戳戳穿插了一个翻页记录勾选值的内容。

没办法一言以蔽之,要求的效果如下图:

image.png

那就记录一下两种实现方法。

① 用一个数组记录选中的行id tbSelIds: [selIds]

② 用MAP记录每页选中的行id,键值对tbSelIdMap: { pageNo: [selIds] }

单个数组记录

实现思路

把选中的行数据id都记录起来存到tbSelIds中;翻页的时候,比对当前页数据id是存在tbSelIds中,是就勾选起来。

用一个数组存,可以解决测试小朋友说的·这个搜索完怎么没有勾上呀;这个怎么修改一页几条,没有勾上呀;这个错乱不好的吧·

听到这些真想脸滚键盘。

需要处理的场景:

① 左侧表格,选中复选框,记录选中的id

② 左侧表格,去掉勾选复选框,去掉选中的id

③ 输入搜索条件/切换页码/切换分页条数,搜索后,将页码中被勾选过的值,自动勾上

④ 右侧表格移除选项,自动从左侧表格中去掉勾选。

看,多简单,处理完这四个就好。

遇到的问题

  1. el-table表格,勾选、去掉勾选,@selection-change方法回调的参数值是,当前页选中的所有行。它没有回调谁被删除了 :) --- 解决方法,当前页选中的,对比已选值,中间的差值,就是去掉勾选的。
  2. el-table表格将表格选上的方法只有两种,全选toggleAllSelection和勾选某一个toggleRowSelection :) --- 但是好恶熏,多个要自动勾上的值,一个一个勾上的时候,就和1↑冲突了。没选的被当做删了,所以加了一个waitSelIds等待选中的值,综合判断。
  3. 切换页码的时候,会自动清空所有选项 :)

贴贴代码

选中复选框

/**
  * 选中复选框
  */
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失业如何如何,失业了开滴滴、跑外卖。不如趁早规划。说的都对,但还是不要焦虑,脚踏实地做好每件事。

「悲观者永远正确,乐观者永远前行」