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>
相关推荐
野槐26 分钟前
Electron开发
前端·javascript·electron
#做一个清醒的人26 分钟前
【Electron】开发两年Electron项目评估报告
前端·electron
lizhongxuan6 小时前
Claude Code 防上下文爆炸:源码级深度解析
前端·后端
天真萌泪7 小时前
JS逆向自用
开发语言·javascript·ecmascript
柳杉8 小时前
震惊!字符串还能这么玩!
前端·javascript
是上好佳佳佳呀8 小时前
【前端(五)】CSS 知识梳理:浮动与定位
前端·css
仍然.9 小时前
算法题目---模拟
java·javascript·算法
wefly20179 小时前
纯前端架构深度解析:jsontop.cn,JSON 格式化与全栈开发效率平台
java·前端·python·架构·正则表达式·json·php
我命由我1234510 小时前
React - 类组件 setState 的 2 种写法、LazyLoad、useState
前端·javascript·react.js·html·ecmascript·html5·js
聊聊MES那点事10 小时前
JavaScript图表控件AG Charts使用教程:使用AG Charts React实时更新柱状图
开发语言·javascript·react.js·图表控件