表格?跨页选择?还要搜索和修改每页?

前前言

写完之后才发现已经有人写了类似的实现了。。。

什么,你还不会 vue 表格跨页多选?

嗨呀(摊手)

不过测试了一下 这个实现方案 有一个局限就是没法响应toggleRowSelection的选择。哈!

不过人家的文章确实写的好哇,学习了学习了。

前言

因为业务中经常遇到需要做表格的跨页选择的需求;但element-ui并不具备相应的功能,所以封装了一个比较通用(不限于element-ui)的工具类来实现。

需要考虑的点

  • 表格有多页且可以切换,需要在已选数据出现的时候,重新勾选上。
  • 表格每页数量可以修改,也需要搜索过滤的功能,所以用页码映射的方式并不可行。

原理

element-ui 表格的 selection-change 事件只会返回当前页的已选值。

即使对比新旧已选的两个数组,也无法确定在新数组中缺失的元素是因为跨页还是因为被取消选中。

核心思路的根据 表格 的 selection-change 事件只会返回当前页所有已选数据的特性。

  • 在切页前后,将【当前页的已选值】从【所有已选值】的map中弹出,放到【编辑中】的map中。

  • 在选择时 selection-change的事件监听处理函数中,把入参的当前页是所有已选值转换成map并赋值给【编辑中】的map。

  • 在切页前将【编辑中】map的值塞入【所有已选值】的map中。

特殊说明:为了便于查询,表格数据转的map都使用id作为key,所以需要保证数据项都有一个唯一的id值。

工具类的实现

js 复制代码
  class TableCrossPageSelectHelper {
    constructor({
      getTableData = () => [], // 获取表格数据的方法
      setInSelected = () => ({}), // 将选中状态写入的方法
    } = {}) {
      this.selectingTableMap = {}; // 当前页选中中的map
      this.selectedTableMap = {}; // 其他页已选的map
      this.getTableData = getTableData;
      this.setInSelected = setInSelected;
    }
    // 获取所有可选值
    getAllSelectedData() {
      return Object.values({ ...this.selectingTableMap, ...this.selectedTableMap });
    }
    // 把当前页数据从已选map中弹出,放到选择中的map
    popCurrentPageSelectedData() {
      this.getTableData().forEach(d => {
        if (!this.selectedTableMap[d.id]) return;
        // element-ui可以注释掉这行 
        // 因为调用toggleRowSelection方法的时候,对应的select-change事件会被触发
        this.selectingTableMap[d.id] = d;
        
        delete this.selectedTableMap[d.id];
        this.setInSelected(d)
      });
    }
    pushCurrentPageSelectingData() {
      Object.assign(this.selectedTableMap, this.selectingTableMap);
      // element-ui可以注释掉这行,table数据切换的时候自己会触发select-change事件 
      // 从而在updateSelectingTableMap清空
      this.selectingTableMap = {};
    }
    // 记录当前页的已选值
    updateSelectingTableMap(selectedDataList) {
      this.selectingTableMap = selectedDataList.reduce((map, d) => {
        map[d.id] = d;
        return map;
      }, {});
    }
  }

demo

js 复制代码
<template>
  <div>
    <el-table
      ref="multipleTable"
      :data="tableData"
      tooltip-effect="dark"
      style="width: 100%"
      @selection-change="onSelectionChange"
    >
      <el-table-column type="selection" width="55"> </el-table-column>
      <el-table-column label="日期" width="120">
        <template slot-scope="scope">{{ scope.row.date }}</template>
      </el-table-column>
      <el-table-column prop="name" label="姓名" width="120"> </el-table-column>
      <el-table-column prop="address" label="地址" show-overflow-tooltip>
      </el-table-column>
    </el-table>
    <button @click="loadData">切页</button>
  </div>
</template>

<script>

import TableCrossPageSelectHelper from './TableCrossPageSelectHelper' 

export default {
  name: 'TableText',
  data() {
    return {
      tableData: [],
      tableCrossPageSelectHelper: new TableCrossPageSelectHelper(),
      tableData1: [
        {
          id: '1',
          date: '2016-05-03',
          name: '页面一-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '2',
          date: '2016-05-02',
          name: '页面一-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '3',
          date: '2016-05-04',
          name: '页面一-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '4',
          date: '2016-05-01',
          name: '页面一-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '5',
          date: '2016-05-08',
          name: '页面一-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '6',
          date: '2016-05-06',
          name: '页面一-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '7',
          date: '2016-05-07',
          name: '页面一-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
      ],
      tableData2: [
        {
          id: '8',
          date: '2016-05-03',
          name: '页面二-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '9',
          date: '2016-05-02',
          name: '页面二-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '10',
          date: '2016-05-04',
          name: '页面二-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '11',
          date: '2016-05-01',
          name: '页面二-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '12',
          date: '2016-05-08',
          name: '页面二-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '13',
          date: '2016-05-06',
          name: '页面二-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
        {
          id: '14',
          date: '2016-05-07',
          name: '页面二-王小虎',
          address: '上海市普陀区金沙江路 1518 弄',
        },
      ],
    };
  },
  methods: {
    onSelectionChange(selectedDataList) {
      this.tableCrossPageSelectHelper.updateSelectingTableMap(selectedDataList);
    },
    queryData() {
      return Promise.resolve(
        this.tableData === this.tableData1 ? this.tableData2 : this.tableData1
      );
    },
    loadData() {
      // 切页前将数据推入
      this.tableCrossPageSelectHelper.pushCurrentPageSelectingData();
      this.queryData()
        .then(res => {
          this.tableData = res;
        })
        .then(() => {
          // 这里要延后处理,保证时机在table清空旧已选值之后
          setTimeout(() => {
            this.tableCrossPageSelectHelper.popCurrentPageSelectedData();
          }, 100);
        });
    },
  },
  mounted() {
    this.loadData();
    this.tableCrossPageSelectHelper = new TableCrossPageSelectHelper({
      getTableData: () => this.tableData,
      setInSelected: (d) => this.$refs.multipleTable.toggleRowSelection(d, true),
    });
  },
};
</script>

<style lang="less" scoped></style>
相关推荐
i听风逝夜4 小时前
Web 3D地球实时统计访问来源
前端·后端
iMonster4 小时前
React 组件的组合模式之道 (Composition Pattern)
前端
呐呐呐呐呢4 小时前
antd渐变色边框按钮
前端
元直数字电路验证5 小时前
Jakarta EE Web 聊天室技术梳理
前端
wadesir5 小时前
Nginx配置文件CPU优化(从零开始提升Web服务器性能)
服务器·前端·nginx
牧码岛5 小时前
Web前端之canvas实现图片融合与清晰度介绍、合并
前端·javascript·css·html·web·canvas·web前端
灵犀坠5 小时前
前端面试八股复习心得
开发语言·前端·javascript
9***Y485 小时前
前端动画性能优化
前端
网络点点滴5 小时前
Vue3嵌套路由
前端·javascript·vue.js
牧码岛5 小时前
Web前端之Vue+Element打印时输入值没有及时更新dom的问题
前端·javascript·html·web·web前端