一、先看效果:

二、完整代码:

<template>
  <el-table :data="tableData" style="width: 100%" :span-method="objectSpanMethod" border>
    <el-table-column prop="city" label="城市" align="center" />
    <el-table-column prop="name" label="名称" align="center" />
    <el-table-column prop="life" label="生活" align="center" />
    <el-table-column prop="ind" label="农业" align="center" />
    <el-table-column prop="agr" label="工业" align="center" />
    <el-table-column prop="eco" label="灌溉" align="center" />
  </el-table>
</template>

<script setup>
import { reactive, onMounted } from 'vue';

// 存放所有的表头 一定要与tableData一致
const colFields = reactive(["city", "name", "life", "ind", "agr", "eco"]);

//存储合并单元格的开始位置
const spanArr = reactive([]);

// 表格数据
const tableData = reactive([
  {
    "city": "北京",
    "name": "站点A",
    "life": "0.0",
    "ind": "50.0",
    "agr": "0.0",
    "eco": "0.0"
  },
  {
    "city": "北京",
    "name": "站点B",
    "life": "0.0",
    "ind": "0.0",
    "agr": "0.0",
    "eco": "580.0"
  },
  {
    "city": "北京",
    "name": "站点C",
    "life": "0.0",
    "ind": "0.0",
    "agr": "0.0",
    "eco": "570.0"
  },
  {
    "city": "上海",
    "name": "站点1",
    "life": "0.0",
    "ind": "401.76",
    "agr": "267.84",
    "eco": "535.68"
  },
  {
    "city": "上海",
    "name": "站点2",
    "life": "0.8",
    "ind": "267.84",
    "agr": "0.0",
    "eco": "638.82"
  },
  {
    "city": "上海",
    "name": "站点3",
    "life": "259.13",
    "ind": "259.14",
    "agr": "818.25",
    "eco": "0.0"
  },
  {
    "city": "广州",
    "name": "站点A",
    "life": "0.0",
    "ind": "0.0",
    "agr": "173.0",
    "eco": "0.0"
  },
  {
    "city": "广州",
    "name": "站点B",
    "life": "503.0",
    "ind": "0.0",
    "agr": "300.0",
    "eco": "0.0"
  },
]);


// 获取并计算表格单元格合并信息
const getSpanArr = () => {
  for (let i = 0; i < tableData.length; i++) {
    let row = i;
    if (row === 0) {
      for (let j = 0; j < colFields.length; j++) {
        spanArr[i * colFields.length + j] = {
          rowspan: 1,
          colspan: 1,
        };
      }
    } else {
      for (let j = 0; j < colFields.length; j++) {
        // 如果当前行和上一行相同的数据,进行合并
        // 添加筛选条件 指定要合并哪些列
        if (colFields[j] == 'city' || colFields[j] == 'name' || colFields[j] == 'life' || colFields[j] == 'agr') {
          // 动态合并相同数据单元格(指定列+合并条件)有时候我们会遇到不想合并的单元格 例如:交叉错开的合并
          // 哪些不合并: Grade不一样的,不合并 避免交叉错开的合并
          if (tableData[row]["city"] !== tableData[row - 1]["city"]) {
            spanArr[row * colFields.length + j] = {
              rowspan: 1,
              colspan: 1,
            };
          } else if (tableData[row][colFields[j]] === tableData[row - 1][colFields[j]]) {
            let beforeItem = spanArr[(row - 1) * colFields.length + j];
            spanArr[row * colFields.length + j] = {
              rowspan: 1 + beforeItem.rowspan, // 合并几行
              colspan: 1, // 这里只是跨行,不跨列
            };
            beforeItem.rowspan = 0;
            beforeItem.colspan = 0;
          } else {
            spanArr[row * colFields.length + j] = {
              rowspan: 1,
              colspan: 1,
            };
          }
        } else {
          spanArr[row * colFields.length + j] = {
            rowspan: 1,
            colspan: 1,
          };
        }
      }
    }
  }

  // 对数据进行倒序
  let stack = [];
  for (let i = 0; i < colFields.length; i++) {
    for (let j = 0; j < tableData.length; j++) {
      if (j === 0) {
        if (spanArr[j * colFields.length + i].rowspan === 0) {
          stack.push(spanArr[j * colFields.length + i]);
        }
      } else {
        if (spanArr[j * colFields.length + i].rowspan === 0) {
          stack.push(spanArr[j * colFields.length + i]);
        } else {
          stack.push(spanArr[j * colFields.length + i]);
          while (stack.length > 0) {
            let pop = stack.pop();
            let len = stack.length;
            spanArr[(j - len) * colFields.length + i] = pop;
          }
        }
      }
    }
  }
};

// 返回合并单元格的方法,供模板中使用
const objectSpanMethod = ({ rowIndex, columnIndex }) => {
  return spanArr[rowIndex * colFields.length + columnIndex];
};

// 在组件挂载时调用 getSpanArr
onMounted(() => {
  getSpanArr();
});
</script>

三、重点:

四、参考:

el-table表格动态合并相同数据单元格(可指定列+自定义合并)_el-table 合并单元格动态-CSDN博客

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐