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

这篇具有很好参考价值的文章主要介绍了Element UI 多选表格【翻页多选】全能版(含翻页多选数据反显、toggleRowSelection失效的原因解析和解决方案)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

效果预览

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

实现思路

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

技术难点

1. 不能使用 selection-change 的原因

selection-change 的参数为当前页选中的所有行,在每次重新获取数据渲染表格时(如翻页时),参数为一个空数组,会导致历史选中的数据被清空!

即便使用 :reserve-selection="true" 来保留历史选中记录也无法达到预期效果。

2. toggleRowSelection失效的原因解析和解决方案

toggleRowSelection失效通常为以下两种情况:

(1)表格数据发生变化,表格还没渲染完便执行了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
    );
  });

完整范例代码

<template>
  <div class="mainBox">
    <h3>已选择:</h3>
    <el-tag
      :key="item[UID]"
      v-for="(item, index) in selectedList"
      closable
      @close="removeItemByIndex(index, item)"
    >
      {{ item.name }}
    </el-tag>

    <el-table
      v-loading="loading"
      ref="multipleTable"
      :data="tableData"
      @select="selectChange"
      @select-all="selectAllChange"
    >
      <el-table-column type="selection" width="55" align="center">
      </el-table-column>
      <el-table-column prop="ID" label="编号" align="center"> </el-table-column>
      <el-table-column prop="name" label="姓名" align="center">
      </el-table-column>
      <el-table-column prop="age" label="年龄" align="center">
      </el-table-column>
    </el-table>
    <el-row type="flex" class="pageBanner" justify="center">
      <el-pagination
        background
        :total="total"
        :page-size="pageSize"
        @size-change="pageSizeChange"
        @current-change="currentPageChange"
        :current-page="currentPage"
        :page-sizes="[1, 2, 3]"
        layout="total, sizes, prev, pager, next, jumper"
      >
      </el-pagination>
    </el-row>
  </div>
</template>
<script>
export default {
  data() {
    return {
      // 唯一标识符
      UID: "ID",
      loading: false,
      total: 0,
      pageSize: 3,
      currentPage: 1,
      selectedList: [
        {
          ID: 1,
          name: "王小虎",
          age: 10,
        },
      ],
      tableData: [],
    };
  },

  mounted() {
    // 页面初始化时,首次加载数据
    this.getData(this.currentPage, this.pageSize);
  },

  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);
          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
          );
        });
      }
    },
  },
};
</script>
<style  scoped>
.mainBox {
  margin: 30px;
}
.el-tag {
  margin: 10px;
}
.pageBanner {
  margin: 10px;
}
</style>

化为己用

若你的唯一标识符不是 ID,则修改 data() 中的UID 的值即可!文章来源地址https://www.toymoban.com/news/detail-409383.html

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

到了这里,关于Element UI 多选表格【翻页多选】全能版(含翻页多选数据反显、toggleRowSelection失效的原因解析和解决方案)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • element-ui中的el-table实现分页多选功能

    selection-change事件:当选择项发生变化时会触发该事件(当分页切换时,选中的数据都会自动清空) 链接: https://blog.csdn.net/qq_36157085/article/details/122922678

    2024年02月17日
    浏览(45)
  • Element UI 表格单选、多选情景

    最近在使用Element UI编写简单前端页面时会遇到需要对表格进行选择操作的场景。在网络上面查询资料时发现实现方式多的看花眼,索性自己总结一个。 话不多说,搬代码来看看~ 单选: 从单选这一块需求来看,至少满足下面两点才能算是完成: 全选框的点击只能取消其他

    2024年02月11日
    浏览(43)
  • < element-Ui表格组件:表格多选功能回显勾选时因分页问题,导致无法勾选回显的全部数据 >

    在 Vue + elementUi 开发中,elementUI中表格在本身是自带多选功能的,但是在某些情况下,并不能完全适用,甚至可能产生bug。例如本次案例所遇Bug,情景如下: 本案例场景 :在表单中, 通过表单参数筛选某个明细表格数据 ,后端要求新增时可多选明细表格中的内容。但由于明

    2024年02月09日
    浏览(57)
  • element ui 树形-懒加载-表格-多选 勾选问题

            row-key=\\\"id\\\"         lazy         :load=\\\"load\\\"         :tree-props=\\\"{           children: \\\'children\\\',           hasChildren: \\\'hasChildren\\\',         }\\\" 1、勾选父级时子级不会勾选上 一般我们实现表格多选功能是这样的:这里不再使用这种方式  第一步:需要我们手动写个勾选表头

    2023年04月09日
    浏览(36)
  • vue Element-ui 表格多选 修改选中行背景色

    转自:https://www.cnblogs.com/Amerys/p/14688342.html 整体思路方式: 1、给获取到的数据添加自定义的className 2、在点击行(row-click)和手动点击勾选框的事件(select-all)中获取到当前的row的className,直接修改className即可 点击查看事件说明 3、在行的 className 的回调方法中(row-class-name)直接返回

    2024年02月11日
    浏览(54)
  • element-UI表格中多选框回显默认选中

    1、通过@selection-change=\\\"handleSelectionChange\\\"获取勾选的数据 2、通过this.$refs.multipleTable.toggleRowSelection(row, true);将数据回显 注意:toggleRowSelection方法的row数据必须是从tableData中获取  

    2024年02月12日
    浏览(44)
  • element-ui的el-table表格复选框只能单选,不可多选

    element的el-table表格复选框只能选中一条,选择下一条,上一条去掉勾选。使用文档中select方法,el-table绑定一个ref。具体代码实现如下 toggleRowSelection:用于多选表格,切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否(selected 为 true 则选中) 

    2024年02月11日
    浏览(56)
  • 随手记:vue2 使用element UI table表格的单选多选反选思路

    selection-change 参数只有一个selection : 可以获取到当前勾选的row的数据,勾选自动行程数组 @selection-change=\\\"handleSelectionChange\\\"    // 多选框选中数据     handleSelectionChange(selection) {         //selection 是勾选中的数组     },  select 参数 selection 选中的数组  row 当前选中的单条数

    2024年04月26日
    浏览(35)
  • Element-UI中el-table内嵌el-popover,在表格翻页后el-popover无法显示问题解决

    由于开发需求,需要在el-table某一列增加popover弹窗,当用户点击按钮时,通过popover组件展示详细信息。参考Element-ui官网文档案例,得出代码如下 具体实现细节无需关注,经过测试后表格第一页的popover组件能够正常显示,但是当翻到第二页时,点击详情按钮,函数能够被正常

    2024年02月11日
    浏览(51)
  • 【实操】vue+element UI tab页多表单合并校验提交

    一个页面中tab栏切换多个form表单组件,只有一个保存按钮。需要把各组件下的表达数据合并校验提交。 父组件通过两次调用$refs获取子组件的dom元素以及组件内部form的dom元素。 通过循环表单项获取validate值获取校验结果,通过Promise.all合并表单。 子组件内部getData方法返回表

    2024年02月11日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包