el-table和分页保持选中状态,点击右边的删除可以取消选中状态,包含取消另一页的数据

首先我的页面的需求是,一个el-table,可以分页,然后右边是自己写的一个选中的所有的数据展示,点击右边的删除按钮,可以删除选中的一条数据,并且在表格中删除选择的状态。我的这个需求死右侧选中的数据只能一条一条的删除,但表格中可以全选和取消全选。以下提供表格能全选和不能全选的方法。

遇到的问题:

因为我右边展示的数据的字段和左侧表格的字段不一致,所以每次点击删除另一页数据的时候就会默认的在右侧有新增一条,并且使用selection-change的方法的时候,返回的数组总数成倍增加。

解决方法:

方法一:

表格不能全选

如果不涉及全选的情况,可以使用select方法,每次一选择的时候就判断右侧的展示数组中是否有这一条数据,若有,则删除,若没有则增加。具体实现代码如下:
下面展示一些 内联代码片

//rightArr右侧的展示数组, select方法中的代码
let objIndex = this.rightArr.findIndex(
        (item) => item.id === row.enpId
      );
      if (objIndex != -1) {
        this.rightArr.splice(objIndex, 1);
      } else {
        let obj = {
          name: row.companyName,
          pname: row.orgName,
          id: row.enpId,
        };
        this.rightArr.unshift(obj);
      }
//请求接口成功后的代码:treeList 左侧表格的数据,如要回显也是同样的实现
   this.treeList = res.data.records || [];
          this.pageInfo.total = Number(res.data.total);
          this.$refs.multipleTable.clearSelection() //这一步非常重要
          if (this.rightArr.length > 0) {
            this.$nextTick(() => {
              this.treeList.forEach((item) => {
                let obj = this.rightArr.find((val) => val.id === item.enpId);
                if (obj) {
                  this.$refs.multipleTable.toggleRowSelection(item, true);
                } 
              });
            });
          }
//右侧点击删除时的方法: 
 let templateIndex = this.treeList.findIndex(item => item.enpId == info.id)
      if(templateIndex != -1) {
         this.$refs.multipleTable.toggleRowSelection(this.treeList[templateIndex]);
      } // 如果在删除的数据在当前页,那么直接改变他的选中状态,因为使用这个方法改变选中状态,并不会出发select方法,所以需要自己手动删除右侧选中的数据
      this.rightArr.splice(index, 1); //删除右侧的选择的那一条数据

方法二:

表格能够全选

假如需求是表格能够全选,那么上面的方法就不适用,因为点击全选的那个框,同样也出发不了select这个方法,那么之前说的遇到的问题就出现了,该怎样解决呢。后来我发现,因为我给右侧的数组有使用map,所以点击右侧的删除之后,在表格selection-change方法就有一点儿识别不清楚当前的操作,就会重复的增加当前页面的选中的数组。导致直接使用this.$refs.multipleTable.toggleRowSelection(row)表格就不能取消选中的状态。不知道能不能看懂我说的,没事,我自己应该能懂。话不多说,上我自己后来解决好的代码:

// 前提条件:el-table需要增加 :row-key="getRowKeys"    type="selection"的列中加 :reserve-selection="true"
getRowKeys方法:
  getRowKeys(row) {
      // console.log("🚀 ~ getRowKeys ~ row:", row);
      return row.enpId; // id是表格数据的唯一标识字段
    },
// 请求接口成功后的部分代码:
    if (this.rightArr.length > 0) {
            this.$nextTick(() => {
              this.treeList.forEach((item) => {
                let obj = this.rightArr.find((val) => val.enpId === item.enpId);
                if (obj) {
                  this.$refs.multipleTable.toggleRowSelection(item, true);
                } else {
                  this.$refs.multipleTable.toggleRowSelection(item, false);
                }
              });
            });
          }
假如需要回显:在回显请求的接口中的部分代码
 const arr = res.data.enps
            this.rightArr = [...arr];
            this.oldSelectData = JSON.parse(JSON.stringify(this.rightArr)); //这个数组非常重要,因为我不知道是不是我哪儿写着有问题,后面需要回显的时候,改变的都会是这个数组
            if (this.rightArr.length > 0) {
              console.log("🚀 ~ .then ~ this.rightArr:", this.rightArr);
              this.$nextTick(() => {
                this.treeList.forEach((item) => {
                  let obj = this.rightArr.find((val) => val.id === item.enpId);
                  if (obj) {
                    this.$refs.multipleTable.toggleRowSelection(item, true);
                  } else {
                    this.$refs.multipleTable.toggleRowSelection(item, false);
                  }
                });
              });
            }
//selection-change方法,对了,还有一个是否点击了下方表格的字段clicked 
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/298a5a270a0148dab69fd37cc8dadd3c.png)

上面是我表格绑定的方法
   handleSelectionChange(data) {
      if (!this.edit) { // 判断是否编辑修改
        if (data.length > 0) {
          this.rightArr = data.map((row) => {
            return {
              orgName: row.companyName,
              pname: row.orgName,
              enpId: row.enpId,
            };
          });
        } else {
          this.rightArr = [];
        }
      } else {
        this.rightArr = this.oldSelectData;
      }
    },
   handleAelectAll(data) { 
      this.clicked = true;
      if (data.length > 0) {
        data.forEach((row) => {
          let objIndex = this.rightArr.findIndex(
            (item) => item.enpId === row.enpId
          );
          if (objIndex == -1) {
            let obj = {
              orgName: row.companyName,
              pname: row.orgName,
              enpId: row.enpId,
            };
            this.rightArr.unshift(obj);
          }
        });
      }
    },
    handleSelect(date, row) {
      this.clicked = true;
      if (this.edit) {
        let objIndex = this.oldSelectData.findIndex((i) => i.id === row.enpId);
        if (objIndex != -1) {
          this.oldSelectData.splice(objIndex, 1);
        } else {
          let obj = {
            orgName: row.companyName,
            pname: row.orgName,
            enpId: row.enpId,
            id: row.enpId,
          };
          this.oldSelectData.unshift(obj);
        }
      }
    },
点击右侧的删除时候的方法:
handleDelete(info, index) {
      if (!this.edit) {
        let templateIndex = this.treeList.findIndex(
          (el) => el.enpId == info.enpId
        );
        console.log("🚀 ~ handleDelete ~ templateIndex:", templateIndex);
        if (templateIndex != -1) {
          this.$refs.multipleTable.toggleRowSelection(
            this.treeList.find((el) => el.enpId == info.enpId),
            false
          ); //注意注意: 在新增的情况下,如果使用了map修改了右侧数据的,这儿这个false非常关键,明确的告诉左侧的表格,取消这条数据的选中状态,不明确的增加false的话就会出现问题,而且当前页面能够找到删除的这条数据的时候,改变了他的数据状态,会自动触发select-change这个方法,所以就不能再手动删除右侧选择的数据了,没有在当前表格页找到,才需要手动删除
        } else {
          this.rightArr.splice(index, 1);
        }

        if (this.rightArr.length > 0) { // 通过右侧的数据来为左侧的表格增加每条数据的选中的状态
          this.$nextTick(() => {
            this.rightArr.forEach((item) => {
              let obj = this.treeList.find((el) => el.enpId == item.enpId);
              if (obj) {
                this.$refs.multipleTable.toggleRowSelection(obj, true);
              }
            });
          });
        }
      } else { // 在修改状态下:
        let templateIndex = this.treeList.findIndex(
          (el) => el.enpId == info.enpId
        );
        console.log("🚀 ~ handleDelete ~ 222222templateIndex:", templateIndex);
        if (templateIndex != -1) {
          this.$refs.multipleTable.toggleRowSelection(
            this.treeList.find((el) => el.enpId == info.enpId),
            false
          ); // 这儿的false也是必须要加的,和新增不同的是这儿无论在当前也是否找到删除的那条数据,都必须在oldSelectData的这个数组中删除这条数据
          let objIndex = this.oldSelectData.findIndex(
            (i) => i.id === info.enpId
          );
          this.oldSelectData.splice(objIndex, 1);

          console.log(
            "🚀 ~ handleDelete ~ this.oldSelectData:",
            this.oldSelectData
          );
        } else {
          this.oldSelectData.splice(index, 1);
        }

        if (this.oldSelectData.length > 0) { // 通过oldSelectData这个数组里面的数据来反选表格的选择状态
          this.$nextTick(() => {
            this.oldSelectData.forEach((item) => {
              let obj = this.treeList.find((el) => el.enpId == item.enpId);
              if (obj) {
                this.$refs.multipleTable.toggleRowSelection(obj, true);
              }
            });
          });
        }
      }
      // }
    },
//template里面的右侧的代码
   <div class="users_select users_item">
            <div class="total_info">
              <p>
                已选<span class="bold">{{
                  !edit ? rightArr.length : oldSelectData.length
                }}</span
                >个企业
              </p>
            </div>
            <div class="users" v-loading="rightLoading" v-if="!edit">
              <div
                class="right_user"
                v-for="(item, index) in rightArr"
                :key="index"
              >
                <div class="users_select_content">
                  <div class="users_select_left">
                    <p class="left_name">{{ item.name}}</p>
                  </div>
                  <div
                    v-if="type !== 'view'"
                    class="users_select_right"
                    @click="handleDelete(item, index)"
                  >
                    <i class="el-icon-error"></i>
                  </div>
                </div>
                <div class="users_select_desc">
                  <p class="desc_item desc_item_left">
                    {{ item.pname }}
                  </p>
                </div>
              </div>
            </div>
            <div class="users" v-loading="rightLoading" v-else>
              <div
                class="right_user"
                v-for="(item, index) in oldSelectData"
                :key="index"
              >
                <div class="users_select_content">
                  <div class="users_select_left">
                    <p class="left_name">{{ item.name}}</p>
                  </div>
                  <div
                    v-if="type !== 'view'"
                    class="users_select_right"
                    @click="handleDelete(item, index)"
                  >
                    <i class="el-icon-error"></i>
                  </div>
                </div>
                <div class="users_select_desc">
                  <p class="desc_item desc_item_left">
                    {{ item.pname }}
                  </p>
                </div>
              </div>
            </div>
          </div>

// watch监听
  watch: {
    value: {
      handler(val) { // 当新增或者编辑弹窗展示的时候才开始调用方法
        if (val) {
          this.treeList = [];
          this.getEnpTable(); // 表格的数据请求
          if (this.info) { // 如果传入了info,则表示是编辑
            this.getOldData(); // 需要回显的选中数据请求
            this.clicked = false;
            this.edit = true;
          }
        }
      },
      immediate: true,
    },
  },
页面展示

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值