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

前前言

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

什么,你还不会 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>
相关推荐
别拿曾经看以后~1 小时前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
我要洋人死1 小时前
导航栏及下拉菜单的实现
前端·css·css3
川石课堂软件测试1 小时前
性能测试|docker容器下搭建JMeter+Grafana+Influxdb监控可视化平台
运维·javascript·深度学习·jmeter·docker·容器·grafana
科技探秘人1 小时前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人1 小时前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR1 小时前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香1 小时前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q2498596931 小时前
前端预览word、excel、ppt
前端·word·excel
小华同学ai1 小时前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
problc1 小时前
Flutter中文字体设置指南:打造个性化的应用体验
android·javascript·flutter