el-table 列合并思路

111 阅读1分钟

自定义一个组件 ColumnMergingTable.vue


<template>
  <el-table v-bind="$attrs" :data="data" :span-method="objectSpanMethod">
    <slot></slot>
  </el-table>
</template>

<script setup>
import { defineProps } from 'vue';
import { ElTable } from 'element-plus';

const props = defineProps({
  data: {
    type: Array,
    required: true
  },
  columnsToCheck: {
    type: Array,
    default: () => []
  }
});

const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
  // 当前列是需要检查的列之一时,遍历后续行,检查传入的字段是否都相同,统计相同的行数rowspan。
  // 对于不需要合并的列,返回rowspan: 1和colspan: 1。
  if (props.columnsToCheck.includes(column.property)) {
    let rowspan = 1;
    for (let i = rowIndex + 1; i < props.data.length; i++) {
      let isSame = true;
      for (let prop of props.columnsToCheck) {
        if (props.data[i][prop]!== props.data[rowIndex][prop]) {
          isSame = false;
          break;
        }
      }
      // 确定合并行数:是否都相同,统计相同的行数rowspan
      if (isSame) {
        rowspan++;
      } else {
        break;
      }
    }
    if (rowIndex > 0) {
      let prevIsSame = true;
      for (let prop of props.columnsToCheck) {
        if (props.data[rowIndex][prop]!== props.data[rowIndex - 1][prop]) {
          prevIsSame = false;
          break;
        }
      }
      // 前一行相同,说明这不是合并的起始行,返回rowspan: 0和colspan: 0隐藏该单元格。
      if (prevIsSame) {
        return {
          rowspan: 0,
          colspan: 0
        };
      }
    }
    return {
      rowspan: rowspan,
      colspan: 1
    };
  }
  // 其他列处理:对于不需要合并的列,返回rowspan: 1和colspan: 1。
  return {
    rowspan: 1,
    colspan: 1
  };
};
</script>    

引入组件部分代码

<ColumnMergingTable border :columnsToCheck="columnsToCheck" :data="page.list" height="100%"
        loading="isLoadingData">
        <el-table-column align="center" label="序号" width="55">
          <template #default="{ $index }">
            {{ $index + 1 }}
          </template>
        </el-table-column>
</ColumnMergingTable>
     
export default {
  setup() {
    const columnsToCheck = ref(['companyName', 'companyProjectName']);
    return { columnsToCheck }
  }
}

效果如下

image.png