el-table实现多行合并、选择(解决合并导致的半选问题)、删除操作

背景

有个页面有这个需求,多行合并、编辑、删除、多选、header添加筛选条件

主要解决问题

  1. 表格多行合并
  2. 解决合并导致的单选、多选和状态为半选的问题
  3. 删除统一行数
  4. header筛选

没法给图,直接给代码

代码

复制代码
<template>
  <div>
    <el-table
      ref="multipleTableDevice"
      :data="tableData"
      :span-method="objectSpanMethod"
      border
      style="width: 100%; margin-top: 20px"
      @select="selectTab"
    >
      <!-- @selection-change="handleSelectionChange" -->
      <el-table-column prop="id" label="ID" width="180"> </el-table-column>
      <el-table-column
        prop="name"
        label="姓名"
        :filters="[
          { text: '王小虎1', value: '王小虎1' },
          { text: '王小虎2', value: '王小虎2' },
          { text: '王小虎3', value: '王小虎3' },
        ]"
        :filter-method="filterHandler"
      >
      </el-table-column>
      <el-table-column prop="amount1" label="数值 1(元)"> </el-table-column>
      <el-table-column prop="amount2" label="数值 2(元)"> </el-table-column>
      <el-table-column prop="amount3" label="数值 3(元)"> </el-table-column>
      <el-table-column label="操作" width="130" align="center">
        <template>
          <el-button type="text">编辑</el-button>
        </template>
      </el-table-column>
      <el-table-column type="selection" width="55" key="selection" />
    </el-table>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",

  data() {
    return {
      tableData: [
        {
          id: "12987122",
          name: "王小虎1",
          amount1: "234",
          amount2: "3.2",
          amount3: 10,
        },
        {
          id: "12987122",
          name: "王小虎1",
          amount1: "165",
          amount2: "4.43",
          amount3: 12,
        },
        {
          id: "12987122",
          name: "王小虎1",
          amount1: "165",
          amount2: "4.43",
          amount3: 12,
        },
        {
          id: "12987122",
          name: "王小虎1",
          amount1: "165",
          amount2: "4.43",
          amount3: 12,
        },
        {
          id: "12987124",
          name: "王小虎2",
          amount1: "324",
          amount2: "1.9",
          amount3: 9,
        },
        {
          id: "12987124",
          name: "王小虎2",
          amount1: "621",
          amount2: "2.2",
          amount3: 17,
        },
        {
          id: "12987125",
          name: "王小虎3",
          amount1: "539",
          amount2: "4.1",
          amount3: 15,
        },
      ],
    };
  },
  created() {},
  methods: {
    filterHandler(value, row) {
      return row.name === value;
    },
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 仅对第一列(类别列)进行合并
      if (
        columnIndex === 0 ||
        columnIndex === 1 ||
        columnIndex === 2 ||
        columnIndex === 5 ||
        columnIndex === 6
      ) {
        // 查找当前行与上一行是否属于同一类别
        const prevRow = this.tableData[rowIndex - 1];
        if (prevRow && prevRow.name === row.name) {
          // 如果属于同一类别,则当前行设置为不显示(即合并到上一行)
          return { rowspan: 0, colspan: 0 };
        } else {
          // 如果不属于同一类别,计算当前类别连续出现的行数作为rowspan的值
          let count = 1;
          for (let i = rowIndex + 1; i < this.tableData.length; i++) {
            if (this.tableData[i].name !== row.name) {
              break;
            }
            count++;
          }
          return { rowspan: count, colspan: 1 };
        }
      }
    },
    unique(arr, val) {
      const res = new Map();
      return arr.filter((item) => !res.has(item[val]) && res.set(item[val], 1));
    },
    selectTab(val, row) {
      // 当前是选中还是取消 true 选中 false 取消
      let isSelect = val.length && val.indexOf(row) > -1;
      // 当前显示的复选框
      let arr = this.unique(val, "name");
      // 取当前所有选中的框的iD的全集 (过滤未被选中的)
      let arrId = [];
      for (var i = 0; i < arr.length; i++) {
        if (isSelect || (!isSelect && arr[i].id !== row.id)) {
          arrId.push(arr[i].id);
        }
      }
      // 根据选中的id筛选数组
      let rowArrById = this.tableData.filter((item) => {
        return arrId.indexOf(item.id) > -1;
      });
      this.$nextTick(() => {
        this.tableData.forEach((item) => {
          this.$refs.multipleTableDevice.toggleRowSelection(item, false);
        });
        // 根据条件把指定行选中
        rowArrById.forEach((item) => {
          this.$refs.multipleTableDevice.toggleRowSelection(item, true);
        });
      });
    },
  },
};
</script>

<style scoped>
/* 样式调整,根据需要添加 */
</style>

删除功能没做,逻辑是通过id删除相同id的数据即可

如有帮助请点个赞,谢谢

相关推荐
前端 贾公子13 小时前
ElementUI 中 validateField 对部分表单字段数组进行校验时多次回调问题
前端·javascript·elementui
棒棒的唐13 小时前
vue2 elementUI 登录页面实现回车提交登录的方法
前端·javascript·elementui
zhangzuying102613 小时前
基于Vue3 +ElementuiPlus + Dexie.js自研的浏览器插件新建标签页tab
vue.js·typescript·echarts
lichong95113 小时前
【混合开发】vue+Android、iPhone、鸿蒙、win、macOS、Linux之video 的各种状态和生命周期调用说明
android·vue.js·macos
知识分享小能手14 小时前
React学习教程,从入门到精通,React 使用属性(Props)创建组件语法知识点与案例详解(15)
前端·javascript·vue.js·学习·react.js·前端框架·vue
摸鱼的春哥14 小时前
前端程序员最讨厌的10件事
前端·javascript·后端
牧羊狼的狼18 小时前
React 中的 HOC 和 Hooks
前端·javascript·react.js·hooks·高阶组件·hoc
知识分享小能手20 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
luckys.one20 小时前
第9篇:Freqtrade量化交易之config.json 基础入门与初始化
javascript·数据库·python·mysql·算法·json·区块链
魔云连洲20 小时前
深入解析:Vue与React的异步批处理更新机制
前端·vue.js·react.js