Element 的 el-table 表格实现单元格合并

  • html 部分
html 复制代码
<template>
  <div class="index-wapper">
    <el-table :data="tableData" :span-method="objectSpanMethod" border>
      <el-table-column v-for="(item, index) in tableHeader" :key="index" :prop="item.prop" :label="item.label"
        :fixed="item.fixed" align="center"></el-table-column>
    </el-table>
  </div>
</template>
  • js 部分
javascript 复制代码
<script>
export default {
  name: "index-page",
  components: {},
  props: {},
  data() {
    return {
      tableHeader: [
        {
          prop: "country",
          label: "城市",
          fixed: true,
        },
        {
          prop: "title",
          label: "地区",
          fixed: true,
        },
        {
          prop: "data1",
          label: "1",
          fixed: false,
        },
        {
          prop: "data2",
          label: "2",
          fixed: false,
        },
        {
          prop: "data3",
          label: "3",
          fixed: false,
        },
        {
          prop: "data4",
          label: "4",
          fixed: false,
        },
        {
          prop: "data5",
          label: "5",
          fixed: false,
        },
      ],
      tableData: [
        {
          id: 1,
          country: "杭州",
          title: "滨江",
          data1: 0,
          data2: 1,
          data3: 0,
          data4: 1,
          data5: 0,
        },
        {
          id: 2,
          country: "杭州",
          title: "西湖",
          data1: 0,
          data2: 0,
          data3: 0,
          data4: 0,
          data5: 0,
        },
        {
          id: 3,
          country: "杭州",
          title: "余杭",
          data1: 0,
          data2: 1,
          data3: 0,
          data4: 1,
          data5: 1,
        },
        {
          id: 4,
          country: "长沙",
          title: "岳麓",
          data1: 0,
          data2: 0,
          data3: 0,
          data4: 0,
          data5: 1,
        },
        {
          id: 5,
          country: "长沙",
          title: "开福",
          data1: 1,
          data2: 1,
          data3: 0,
          data4: 1,
          data5: 0,
        },
      ],
      spanArr: [],
    };
  },
  mounted() {
    this.getSpanArr();
  },
  methods: {
    /**
     * 合并处理
     */
    getSpanArr() {
      const hLen = this.tableHeader.length;
      // i表示行,j表示列
      for (let i = 0; i < this.tableData.length; i++) {
        if (i === 0) {
          for (let j = 0; j < hLen; j++) {
            this.spanArr[i * hLen + j] = {
              rowspan: 1,
              colspan: 1,
            };
          }
        } else {
          // 当前和上一次的一样,合并所有列的相同数据单元格
          for (let j = 0; j < hLen; j++) {
            // 指定合并哪些列
            if (this.tableHeader[j].prop === "country") {
              // 哪些不合并,country不一样的,不合并
              if (
                this.tableData[i]["country"] !==
                this.tableData[i - 1]["country"]
              ) {
                this.spanArr[i * hLen + j] = {
                  rowspan: 1,
                  colspan: 1,
                };
              } else if (
                this.tableData[i][this.tableHeader[j].prop] ===
                this.tableData[i - 1][this.tableHeader[j].prop]
              ) {
                let beforeItem = this.spanArr[(i - 1) * hLen + j];
                this.spanArr[i * hLen + j] = {
                  rowspan: 1 + beforeItem.rowspan, // 合并几列
                  colspan: 1, // 合并几行
                };
                beforeItem.rowspan = 0;
                beforeItem.colspan = 0;
              } else {
                this.spanArr[i * hLen + j] = {
                  rowspan: 1,
                  colspan: 1,
                };
              }
            }
          }
        }
      }
      // 对数据进行倒序
      let stack = [];
      for (let i = 0; i < hLen; i++) {
        for (let j = 0; j < this.tableData.length; j++) {
          const spanItem = this.spanArr[j * hLen + i];
          if (spanItem) {
            if (spanItem.rowspan === 0) {
              stack.push(spanItem);
            }
            if (j !== 0 && spanItem.rowspan !== 0) {
              stack.push(spanItem);
              while (stack.length > 0) {
                let pop = stack.pop();
                let len = stack.length;
                this.spanArr[(j - len) * hLen + i] = pop;
              }
            }
          }
        }
      }
    },
    /**
     * 表合并规则
     */
    objectSpanMethod({ rowIndex, columnIndex }) {
      return this.spanArr[rowIndex * this.tableHeader.length + columnIndex];
    },
  },
  watch: {},
};
</script>
相关推荐
重生之后端学习3 分钟前
02-前端Web开发(JS+Vue+Ajax)
java·开发语言·前端·javascript·vue.js
布鲁斯的快乐小屋6 分钟前
axios的基本使用
javascript·ajax
繁依Fanyi1 小时前
用 CodeBuddy 实现「IdeaSpark 每日灵感卡」:一场 UI 与灵感的极简之旅
开发语言·前端·游戏·ui·编辑器·codebuddy首席试玩官
黄鹂绿柳3 小时前
Vue+Vite学习笔记
vue.js·笔记·学习
来自星星的坤3 小时前
【Vue 3 + Vue Router 4】如何正确重置路由实例(resetRouter)——避免“VueRouter is not defined”错误
前端·javascript·vue.js
香蕉可乐荷包蛋7 小时前
浅入ES5、ES6(ES2015)、ES2023(ES14)版本对比,及使用建议---ES6就够用(个人觉得)
前端·javascript·es6
未来之窗软件服务8 小时前
资源管理器必要性———仙盟创梦IDE
前端·javascript·ide·仙盟创梦ide
liuyang___9 小时前
第一次经历项目上线
前端·typescript
西哥写代码9 小时前
基于cornerstone3D的dicom影像浏览器 第十八章 自定义序列自动播放条
前端·javascript·vue
清风细雨_林木木9 小时前
Vue 中生成源码映射文件,配置 map
前端·javascript·vue.js