Element UI 多选表格【翻页多选】全能版(含翻页多选数据反显、toggleRowSelection失效的原因解析和解决方案)【转载】

107 阅读1分钟

效果预览

30023838_62e4292ed4a9c78205.gif

实现思路 data中定义 selectedList 数组保存选中的数据 在页面初次渲染、翻页、切换每页数据数量等每次重新获取表格数据渲染表格时,都根据 selectedList 勾选表格中已经选中的行 ​ ​切换单行勾选状态时,判断是选中还是取消选中​​,选中则增加选中项,取消选中则移除选中项。 切换全选和取消全选时,根据当前页选中行的数据进行更新,若选中行已在 selectedList 中则不再重复添加,否则添加,对于其他非选中行若已在selectedList 中,则从 selectedList 中移除。 技术难点

  1. 不能使用 selection-change 的原因 selection-change 的参数为当前页选中的所有行,在每次重新获取数据渲染表格时(如翻页时),参数为一个空数组,会导致历史选中的数据被清空! 即便使用 ​​:reserve-selection="true"​​ 来保留历史选中记录也无法达到预期效果。

  2. toggleRowSelection失效的原因解析和解决方案 toggleRowSelection失效通常为以下两种情况:

(1)表格数据发生变化,表格还没渲染完便执行了toggleRowSelection

解决方案 : 在 nextTick中执行toggleRowSelection//toggleRowSelection需在nextTick 中执行 toggleRowSelection // toggleRowSelection 需在nextTick中使用! this.nextTick(() => { this.refs.multipleTable.toggleRowSelection(row); }); (2)toggleRowSelection的第一个参数不是表格源数据

即便数据的值完全一样也会失效,因为数据为引用类型,必须地址一样。

解决方案 :toggleRowSelection的第一个参数通过在表格数据中通过 find() 查找得到。 this.nextTick(() => { this.refs.multipleTable.toggleRowSelection( // 此处必须在 tableData 中查找对应的数据,否则 toggleRowSelection 会失效 this.tableData.find((row) => { return row[this.UID] === item[this.UID]; }), false ); });

完整范例代码

methods: { // 单行前的勾选状态切换 selectChange(selectedRows, row) { // true为选中, 0或false为取消选中 let selected = selectedRows.length && selectedRows.indexOf(row) !== -1; if (selected) { this.addItem(row); } else { this.removeItem(row); } }, // 全选/取消全选 selectAllChange(selectedRows) { let selectedMarkList = this.selectedList.map((item) => item[this.UID]); // 当前页选中行的标记列表 let pageSelectedMarkList = Array.isArray(selectedRows) ? selectedRows.map((item) => item[this.UID]) : [];

  this.tableData.forEach((row) => {
    if (pageSelectedMarkList.includes(row[this.UID])) {
      if (!selectedMarkList.includes(row[this.UID])) {
        this.addItem(row);
      }
    } else if (selectedMarkList.includes(row[this.UID])) {
      this.removeItem(row);
    }
  });
},
// 切换每页显示条数
pageSizeChange(newPageSize) {
  this.pageSize = newPageSize;
  this.getData(this.currentPage, this.pageSize);
},
// 切换页码--翻页
currentPageChange(newPage) {
  this.currentPage = newPage;
  this.getData(this.currentPage, this.pageSize);
},
// 更新勾选标记
updateMark() {
  let selectedMarkList = this.selectedList.map((item) => item[this.UID]);

  this.tableData.forEach((row) => {
    if (selectedMarkList.includes(row[this.UID])) {
      // toggleRowSelection 需在$nextTick中使用!
      this.$nextTick(() => {
        this.$refs.multipleTable.toggleRowSelection(row);
      });
    }
  });
},

// 模拟访问接口获取数据
getData(page, pageSize) {
  this.loading = true;
  setTimeout(() => {
    let data = [
      {
        ID: 1,
        name: "王小虎",
        age: 10,
      },
      {
        ID: 2,
        name: "张三",
        age: 20,
      },
      {
        ID: 3,
        name: "李四",
        age: 30,
      },
      {
        ID: 4,
        name: "何香",
        age: 18,
      },
      {
        ID: 5,
        name: "刘刀",
        age: 27,
      },
      {
        ID: 6,
        name: "关胜",
        age: 33,
      },
      {
        ID: 7,
        name: "齐巧",
        age: 55,
      },
      {
        ID: 8,
        name: "卢一方",
        age: 45,
      },
      {
        ID: 9,
        name: "王兴海",
        age: 66,
      },
      {
        ID: 10,
        name: "全德",
        age: 100,
      },
    ];

    this.total = data.length;
    let startIndex = pageSize * (page - 1);
    let endIndex = pageSize * page;
    this.tableData = data.slice(startIndex, endIndex);
    this.updateMark();
    this.loading = false;
  }, 1000);
},
// 新增选中项
addItem(item) {
  this.selectedList.push(item);
},
// 移除选中项
removeItem(item) {
  for (let [index, itemTemp] of this.selectedList.entries()) {
    if (itemTemp[this.UID] === item[this.UID]) {
      this.removeItemByIndex(index, item);
      break;
    }
  }
},
// 根据下标移除选中项
removeItemByIndex(index, item) {
  this.selectedList.splice(index, 1);

  // 若有item,则是点击标签上的关闭按钮,移除选中项
  if (item) {
    this.$nextTick(() => {
      this.$refs.multipleTable.toggleRowSelection(
        // 此处必须在 tableData 中查找对应的数据,否则 toggleRowSelection 会失效
        this.tableData.find((row) => {
          return row[this.UID] === item[this.UID];
        }),
        false
      );
    });
  }
},

}, };

.mainBox { margin: 30px; } .el-tag { margin: 10px; } .pageBanner { margin: 10px; }

// 唯一标识符 UID: "ID",