目标:想将分类 、总数量、查看数量数据相同的单元格合并
合并前的效果
合并后的效果
思路:
- 定义了
objectSpanMethod
函数,它是一个用于计算合并单元格的方法 -
需要进行合并的列,首先获取当前单元格的值,然后获取上一行相同列的值。
-
如果当前值和上一行的值相同,说明需要隐藏当前单元格,因此返回
{ rowspan: 0, colspan: 0 }
来指定合并行和合并列的数量为0,从而隐藏该单元格。 -
如果当前值和上一行的值不相同,说明需要进行合并单元格操作。首先将
rowspan
设置为1,表示当前单元格跨越的行数为1。 -
然后使用一个循环从当前行的下一行开始遍历,逐行比较后续行的值与当前值是否相同。如果相同,将
rowspan
加1,继续循环直到不相同为止。 -
最后返回一个对象
{ rowspan, colspan: 1 }
,其中rowspan
表示当前单元格跨越的行数,colspan
表示当前单元格跨越的列数为1(不进行列合并)
Vue2实现代码:
<template>
<el-table
:data="tableData"
:span-method="objectSpanMethod"
border
style="width: 100%; margin-top: 20px"
>
<el-table-column prop="title" label="分类" width="180" />
<el-table-column prop="all" label="总数量" width="180" />
<el-table-column prop="see" label="查看数量" />
<el-table-column prop="content" label="内容" />
<el-table-column prop="remark" label="备注" />
</el-table>
</template>
<script>
export default {
data() {
return {
tableData: [
{
title: "测试",
all: 7,
see: 3,
content: "你好,我在学习",
remark: "备注备注备注",
},
{
title: "测试",
all: 7,
see: 3,
content: "你好,我在学习合并",
remark: "备注备注备注",
},
{
title: "测试",
all: 7,
see: 3,
content: "你好,我在学习合并单元格",
remark: "备注备注备注",
},
{
title: "测试",
all: 7,
see: 3,
content: "你好,我在学习合并单元格1111",
remark: "备注备注备注",
},
{
title: "1234",
all: 6,
see: 4,
content: "222222",
remark: "备注备注备注",
}, {
title: "1234",
all: 6,
see: 4,
content: "222222222",
remark: "备注备注备注",
},
{
title: "置顶",
all: 5,
see: 1,
content: "你好,我在学习合并单元格",
remark: "备注备注备注",
},{
title: "置顶",
all: 5,
see: 1,
content: "你好,我在学习合并单元格",
remark: "备注备注备注",
},{
title: "置顶",
all: 5,
see: 1,
content: "你好,我在学习合并单元格",
remark: "备注备注备注",
},{
title: "置顶",
all: 5,
see: 1,
content: "你好,我在学习合并单元格",
remark: "备注备注备注",
},
],
};
},
methods: {
// 里面包含当前行 row、
// 当前列 column、
// 当前行号 rowIndex、
// 当前列号 columnIndex 四个属性。
// 该函数可以返回一个包含两个元素的数组,
// 第一个元素代表 rowspan 合并行,
// 第二个元素代表 colspan 合并列
objectSpanMethod({
row, // 行
column, // 列
rowIndex, // 行索引
columnIndex, // 列索引
}) {
//想合并哪一列,自行更改判断条件 当前列的索引从0开始计算
if (columnIndex === 0 || columnIndex === 1 || columnIndex === 2 ) {
// 获取当前单元格的值
const currentValue = row[column.property];
// 获取上一行相同列的值
const preRow = this.tableData[rowIndex - 1];
const preValue = preRow ? preRow[column.property] : null;
// 如果当前值和上一行的值相同,则将当前单元格隐藏
if (currentValue === preValue) {
return { rowspan: 0, colspan: 0 };
} else {
// 否则计算当前单元格应该跨越多少行
let rowspan = 1;
for (let i = rowIndex + 1; i < this.tableData.length; i++) {
const nextRow = this.tableData[i];
const nextValue = nextRow[column.property];
if (nextValue === currentValue) {
rowspan++;
} else {
break;
}
}
return { rowspan, colspan: 1 };
}
}
},
},
};
</script>
Vue3实现代码:
<template>
<el-table
:data="tableData"
:span-method="objectSpanMethod"
border
style="width: 100%; margin-top: 20px"
>
<el-table-column prop="title" label="分类" width="180" />
<el-table-column prop="all" label="总数量" width="180" />
<el-table-column prop="see" label="查看数量" />
<el-table-column prop="content" label="内容" />
<el-table-column prop="remark" label="备注" />
</el-table>
</template>
<script setup>
import { ref } from 'vue';
const tableData = ref([
{
title: "测试",
all: 7,
see: 3,
content: "你好,我在学习",
remark: "备注备注备注",
},
{
title: "测试",
all: 7,
see: 3,
content: "你好,我在学习合并",
remark: "备注备注备注",
},
{
title: "测试",
all: 7,
see: 3,
content: "你好,我在学习合并单元格",
remark: "备注备注备注",
},
{
title: "测试",
all: 7,
see: 3,
content: "你好,我在学习合并单元格1111",
remark: "备注备注备注",
},
{
title: "1234",
all: 6,
see: 4,
content: "222222",
remark: "备注备注备注",
}, {
title: "1234",
all: 6,
see: 4,
content: "222222222",
remark: "备注备注备注",
},
{
title: "置顶",
all: 5,
see: 1,
content: "你好,我在学习合并单元格",
remark: "备注备注备注",
},{
title: "置顶",
all: 5,
see: 1,
content: "你好,我在学习合并单元格",
remark: "备注备注备注",
},{
title: "置顶",
all: 5,
see: 1,
content: "你好,我在学习合并单元格",
remark: "备注备注备注",
},{
title: "置顶",
all: 5,
see: 1,
content: "你好,我在学习合并单元格",
remark: "备注备注备注",
},
]);
function objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0 || columnIndex === 1 || columnIndex === 2) {
const currentValue = row[column.property];
const preRow = tableData.value[rowIndex - 1];
const preValue = preRow ? preRow[column.property] : null;
if (currentValue === preValue) {
return { rowspan: 0, colspan: 0 };
} else {
let rowspan = 1;
for (let i = rowIndex + 1; i < tableData.value.length; i++) {
const nextRow = tableData.value[i];
const nextValue = nextRow[column.property];
if (nextValue === currentValue) {
rowspan++;
} else {
break;
}
}
return { rowspan, colspan: 1 };
}
}
}
</script>