自定义一个组件 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 }
}
}
效果如下
