由于产品的需求,我们在使用element-ui 的table时,可能会用到带复选框的table,但是,这个复选框在我们使用分页切换下一页时,上一页选中没有提交的选项是没有保存的,因为每一页的数据都是直接从接口获取的,基于这种情况,为了记住我们每一页的选项,我这里分享一种方法,于是便写下了这篇文章。
另外还针对这个问题出了第二套方案,我觉得第二套方案更好,小伙伴们如果想节约时间的话可以直接移步第二套方案噢


文章目录

  • 1、插话
  • 2、分析
  • 3、方案
  • 4、实现
  • 5、效果
  • 6、总结


1、插话

有同学可能会说:“我在切换页码时对该页的选项进行保存也可以呀”

是的,这种方法确实可以,但是呢,如果页数过多,我们每一页都有要修改选项时,频繁请求接口,就会对服务器造成一种负担,这明显违背了性能优化的思想。

除此以外,还有一个很重要的原因,那就是,产品说“我不想每一页都点保存,我要每一页都操作结束之后,点一次保存,提交所有被操作的选项”

2、分析

我们都知道造成这种table选择状态没有保存的原因是因为数据刷新与重新渲染,刷新是接口数据返回了新的数据,渲染是根据发生变化的数据渲染,知道了问题所在,我们开始制定实现方法。

3、方案
1、初始化一个changList[]
2、将接口返回的列表数据进行处理,选中状态的添加进changList中
3、渲染数据,根据changList中的项来判断多选框的状态
4、多选框状态改变时将改变的项添加到changList中
5、切换页面的时候则重复2-4的步骤

导图如下:

element 省市区多选联动_elementui

4、实现

script代码

//定义全局变量
const changeList = []

data() {
  return {
    /** 组件自动处理得到的此时选中的选项 */
    multipleSelection: [],
  }
}
//利用计算属性计算changList
computed: {
  changeList() {
  const { multipleSelection } = this
	//比对组件得到的选中数据与changList
  //changList中不存在则push进去
  multipleSelection.map((item) => {
    const { itemId } = item
    const exit = changeList.findIndex(item => item.itemId === itemId) >= 0

    if (!exit) {
      changeList.push({ itemId, state: true })
    }
  })
  return changeList
  }
},
methods: {
	fetchList() {
    /**
    * 此处请求接口获取到后台返回的数据列表list
    */
    //对数据进行渲染
    this.$nextTick(() => {
      this.list.forEach(item => {
        const { itemId } = item
        const exit = changeList.findIndex(items => items.itemId === itemId)
        if (exit >= 0) {
        	this.$refs.multipleTable.toggleRowSelection(item, changeList[exit].state)
        } else {
        	this.$refs.multipleTable.toggleRowSelection(item, item.state)
        }
      })
    })
  } 
}
methods: {
		//此处照搬文档
		handleSelectionChange(val, index) {
      this.multipleSelection = val
    },
		//行选则时的处理逻辑
    handleRowClick(val) {
      const { multipleSelection } = this
      const { itemId } = val
      const state = multipleSelection.findIndex(item => item.itemId === itemId) >= 0

      this.checkChooseState(itemId)
      this.$refs.multipleTable.toggleRowSelection(val, !state)
    },
    //此处关键,由于直接点击checkbox无法直接获取当前行的数据
    //于是我禁用checkbox选择,采用点击checkbox所在行来获取当前行数据
    checkSelectable() {
      return false
    },
		//此处关键 判断变化的选项是否存在于changList中
		//存在则修改状态为false
		//无需在这里添加,我们有计算属性帮我们处理
    checkChooseState(id) {
      changeList.map((item) => {
        const { itemId } = item
        if (id === itemId) {
          item.state = false
        }
      })
    }
}

template代码

<template>
	<el-table
    ref="multipleTable"
    :chang="changList"
    :data="list"
    tooltip-effect="dark"
    style="width: 100%"
    @selection-change="handleSelectionChange"
    @row-click="handleRowClick"
	>
    <el-table-column
      type="selection"
      width="55"
      :selectable="checkSelectable"
    />
    <el-table-column
      prop="liveCompanyName"
      label="公司名"
    />
	</el-table>
</template>

style代码

注释:由于禁用checkbox,它的样式就会变灰,中间的勾也会变灰,所以恢复它的样式,需要添加额外的控制样式的代码

<style lang="less" scoped>
  /deep/ .el-table--enable-row-transition .el-table__body td {
    -webkit-transition: background-color .25s ease;
    transition: background-color .25s ease;
    cursor: pointer;
  }
  /deep/ .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner:after{
    border-color: #fff;
  }
  /deep/ .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner{
    background-color: #409eff;
  }
</style>
5、效果

首次打开table,changList长度由0->2,因为有两个已选项

element 省市区多选联动_vue_02

现在我们选中最后一项,changList长度由2->3

element 省市区多选联动_javascript_03

接下来我们切换到第二页,有7个默认选中项,changList长度由3->10

element 省市区多选联动_javascript_04

这时我们再新增一个选项,changList长度变成了11

element 省市区多选联动_elementui_05

切回第一页长度不变还是11

element 省市区多选联动_element 省市区多选联动_06

我们再新增一项,changList长度变成12

element 省市区多选联动_javascript_07

我们取消一项已选的,现在changList长度还是12,但是取消的那一项的标志变成了false

element 省市区多选联动_element 省市区多选联动_08

最后,我们将changList传给后端即可,里面包含默认项以及用户操作的变化项

6、总结

本来实现的效果是想通过视频的形式分享出来的,可是想着对视频中的数据打码太麻烦就换成了图片,虽然很low,但是也尽量让大家看到效果