Element-UI 表格分页时,选中状态可保存

一、大部分文章的主要误区

代码的部分,借鉴了一下这篇文章,有稍许自己的修改。

https://blog.csdn.net/Ms_alinda/article/details/102861781

  1. 通过属性解决的方法
 <el-table :row-key="rowKey">
     <el-table-column type="selection" :reserve-selection="true"></el-table-column>
</el-table>
methods: {
   rowKey (row) {
      return row.id
    }
}

这种方法无疑是最方便的,因此也是第一个就尝试,但是不知道什么原因,始终会报错

immediate,watcher "data" :Cannot read property  "reduce" of null
具体原因我也没找到,所以就放弃了这中方法了。

  1. 错误引导

    直接将 handleSelectionChange的 val 赋值给数组,再去调用this.$refs.multipleTable.toggleRowSelection(row) 的方法,
    这个方法,在切换分页的时候,val就为空了,
    不知道这些人为什么复制别人文章的时候也不看看对不对。。。。

解决思路

1 、
element提供了一个方法,可以返回每次选择之后的所有选中项的集合。

selection-change 当选择项发生变化时会触发该事件 selection

因此可以根据这个来将每一次的数据在修改过后推送到自定义的选中集合 selectList 中,
不过在此时,每一次选中, selection-change 返回值的集合都是带有原来的值的,因此要为 selectList 去重

handleSelectionChange(val){
 if(val.length>0){
   val.forEach(item=> this.selectList.push(item))
   //对象数组去重
   this.selectList = this.selectList.filter((x, index,self)=>{
     let arrids = []
     let arrnames = []
     this.selectList.forEach((item,i) => {
       arrids.push(item.id)
       arrnames.push(item.name)
     })
     let judgeOne = arrids.indexOf(x.id) === index
     let judgeTwo = arrnames.indexOf(x.name) === index
     return judgeOne || judgeTwo
   })
 }
},

2、
在获取到每一次改变的数据后,直接赋值也是存在漏洞的,如果点击了取消,那么选中的val中不再有这个值,但是 selectList 中还存在这个值,所以也要给单选绑定事件,没有的选项要添加,有的话,就删除

selectItem(selection, row){
//单选的筛选,将没有的数据添加,有的数据删除。
 let flag = this.selectList.every(item => item.id != row.id); 
 if(!flag){
   let unselect =this.selectList.findIndex((item,index) => {
     if(item.id == row.id){
       return index
     }
   })
   this.selectList.splice(unselect,1)
 }
},

3、
单选的状态改变之后,也要考虑多选的状态,因为两个是不同的触发事件,因此要分开考虑。
不过全选的比较简单一些,因为全选选中只需要将所有的选中数据推给selectList,但是在取消全选的时候,就需要将当前全选的数据,也就是当前列表的数据,与selectList对比,然后去重。

selectAll(selection){
  //将原本全选,然后又取消的数据删除
  if(selection.length==0){
    for(let i = 0;i<this.list.length;i++){
      let index 
      index = this.isSelectedGoods(this.list[i], this.selectList)
      if (index > -1) {
        this.selectList.splice(index, 1);
      } else {
        this.selectList.push(this.list[i]);
      }
    }
    console.log(this.selectList)
  }
},

isSelectedGoods(row, list) {
  let rows = JSON.parse(JSON.stringify(row))
   //是否选取 -1表示没选中
   return list.findIndex(item => {
     return item.id == rows.id;
   });
 },

4、
在数据渲染的时候,将选中的状态,与当前数组进行对比,添加选中状态,

setSelect(){
 //设置选中状态
  this.$nextTick(() => {
    if(this.selectList.length && this.selectList.length>0){
      this.list.forEach(row => {
        this.selectList.forEach(p => {
          if (row.id === p.id) {
            this.$refs.multipleTable.toggleRowSelection(row);
          }
        });
      });
    }
  });
},

整体代码

<template>
<div>
    <el-table
      :key="tableKey"
      :data="list"
      @select = "selectItem"
      @select-all ='selectAll'
      @selection-change = 'handleSelectionChange'
      ref="multipleTable"
    >
      <el-table-columntype="selection"></el-table-column>
    </el-table>
    <pagination/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: null,
      selectList:[],
    }
  },
  created() {
    this.getList()
  },
  methods: {
    getList() {
      //获取数据
        this.setSelect()
      })
    },
    selectItem(selection, row){
      //单选的筛选,将没有的数据添加,有的数据删除。
      let flag = this.selectList.every(item => item.id != row.id); 
      if(!flag){
        let unselect =this.selectList.findIndex((item,index) => {
          if(item.id == row.id){
            return index
          }
        })
        this.selectList.splice(unselect,1)
      }
    },
    selectAll(selection){
      //将原本全选,然后又取消的数据删除
      if(selection.length==0){
        for(let i = 0;i<this.list.length;i++){
          let index 
          index = this.isSelectedGoods(this.list[i], this.selectList)
          if (index > -1) {
            this.selectList.splice(index, 1);
          } else {
            this.selectList.push(this.list[i]);
          }
        }
        console.log(this.selectList)
      }
    },
    handleSelectionChange(val){
      if(val.length>0){
        val.forEach(item=> this.selectList.push(item))
        //对象数组去重
        this.selectList = this.selectList.filter((x, index,self)=>{
          let arrids = []
          let arrnames = []
          this.selectList.forEach((item,i) => {
            arrids.push(item.id)
            arrnames.push(item.name)
          })
          let judgeOne = arrids.indexOf(x.id) === index
          let judgeTwo = arrnames.indexOf(x.name) === index
          return judgeOne || judgeTwo
        })
      }
      console.log(this.selectList)
    },
    setSelect(){
      //设置选中状态
      this.$nextTick(() => {
        if(this.selectList.length && this.selectList.length>0){
          this.list.forEach(row => {
            this.selectList.forEach(p => {
              if (row.id === p.id) {
                this.$refs.multipleTable.toggleRowSelection(row);
              }
            });
          });
        }
      });
    },
    isSelectedGoods(row, list) {
      let rows = JSON.parse(JSON.stringify(row))
      //是否选取 -1表示没选中
      return list.findIndex(item => {
        return item.id == rows.id;
      });
    },
  }
}
</script>

全篇有可能有不足的地方,或者冗余的代码,还请指出,一起进步,
感谢参考的文章作者,以及其他搜索到的数组方法,基础知识还是不太好。。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
如果你使用的是 element-ui 的 el-table 组件,并且开启了前端分页,那么默认情况下多选只能选中当前页的数据。 这是因为 el-table 组件默认只渲染当前页的数据,而不是全部数据。如果你想要在多个页面之间进行多选,你需要在 el-table 组件中添加一个自定义的多选列,并且在数据中添加一个属性来表示是否选中。 以下是一个示例代码: ```html <el-table :data="tableData" :span-method="rowSpanMethod" v-loading="loading"> <el-table-column type="selection" width="55"> <template slot-scope="{ row }"> <el-checkbox v-model="row.selected"></el-checkbox> </template> </el-table-column> <el-table-column prop="name" label="Name"></el-table-column> <el-table-column prop="age" label="Age"></el-table-column> <el-table-column prop="address" label="Address"></el-table-column> </el-table> ``` ```javascript export default { data() { return { tableData: [ { name: 'John', age: 18, address: 'New York', selected: false }, { name: 'Sarah', age: 22, address: 'London', selected: false }, { name: 'Tom', age: 25, address: 'Paris', selected: false }, { name: 'Jane', age: 30, address: 'Tokyo', selected: false }, ], loading: false, }; }, methods: { rowSpanMethod({ row, column, rowIndex, columnIndex }) { if (columnIndex === 0) { const rowSpan = this.getRowSpan(row, 'selected'); if (rowSpan > 1) { return { rowspan: rowSpan, colspan: 1, }; } } }, getRowSpan(row, prop) { let rowSpan = 1; for (let i = this.tableData.indexOf(row) + 1; i < this.tableData.length; i++) { if (this.tableData[i][prop] === row[prop]) { rowSpan++; } else { break; } } return rowSpan; }, }, }; ``` 在这个示例中,我们添加了一个名为 `selected` 的属性来表示每一行是否被选中。我们通过在 el-table-column 中添加一个自定义的列来实现多选功能,然后在模板中使用 el-checkbox 组件来绑定每一行的选中状态。我们还使用了一个自定义的 rowSpanMethod 方法来处理多选列的行合并,以便在表格中显示选中的行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值