前言
本文代码使用vue2+element UI,通过给table
传入span-method
方法实现合并行或列
效果图
示例代码
后端返回数据格式如下
{
"total": 12,
"records": [
[
{
"id": 1,
"project": "田径",
"subitem": "100米",
"category": "决赛",
"score": 9.6,
"creator": "张三",
"competitionName": "国际田联锦标赛",
"date": "2023-08-15",
"location": "北京",
"worldRecord": "1",
"asiaRecord": "0"
},
{
"id": 2,
"project": "田径",
"subitem": "100米",
"category": "资格赛",
"score": 10.1,
"creator": "李四",
"competitionName": "全国田径锦标赛",
"date": "2023-09-01",
"location": "上海",
"worldRecord": "0",
"asiaRecord": "0"
}
],
[
{
"id": 3,
"project": "田径",
"subitem": "200米",
"category": "决赛",
"score": 19.2,
"creator": "王五",
"competitionName": "国际田联锦标赛",
"date": "2023-08-15",
"location": "北京",
"worldRecord": "1",
"asiaRecord": "0"
},
{
"id": 4,
"project": "田径",
"subitem": "200米",
"category": "资格赛",
"score": 20.5,
"creator": "赵六",
"competitionName": "全国田径锦标赛",
"date": "2023-09-01",
"location": "上海",
"worldRecord": "0",
"asiaRecord": "0"
}
],
[
{
"id": 15,
"project": "田径",
"subitem": "跳远",
"category": "决赛",
"score": 8.4,
"creator": "马十三",
"competitionName": "国际田联锦标赛",
"date": "2023-08-15",
"location": "北京",
"worldRecord": "0",
"asiaRecord": "1"
},
{
"id": 16,
"project": "田径",
"subitem": "跳远",
"category": "资格赛",
"score": 7.8,
"creator": "李十四",
"competitionName": "全国田径锦标赛",
"date": "2023-09-01",
"location": "上海",
"worldRecord": "0",
"asiaRecord": "0"
}
]
]
}
代码如下
<template>
<div class="record-manage-container">
<el-table :data="recordList" :span-method="mergeCells">
<el-table-column prop="project" label="项目" width="180" />
<el-table-column prop="subitem" label="小项" width="180"/>
<el-table-column prop="category" label="类别" />
<el-table-column prop="score" label="成绩" />
<el-table-column prop="creator" label="创造者" />
<el-table-column prop="competitionName" label="比赛名称" />
<el-table-column prop="date" label="日期" />
<el-table-column prop="location" label="地点" />
<el-table-column prop="worldRecord" label="世界纪录" />
<el-table-column prop="asiaRecord" label="亚洲纪录" />
</el-table>
</div>
</template>
<script>
import { recordList } from "@/api/game/scoreManage";
export default {
data() {
return {
recordList:[],
};
},
created() {
this.getRecordList()
},
methods: {
// 获取纪录列表
getRecordList() {
// 在此处调用获取数据的接口
recordList().then(res => {
// console.log(res)
// 扁平化 records 为一维数组
this.recordList = res.records.flat()
this.total = res.total
})
},
mergeCells({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
// 合并 "项目" 列
const project = row.project;
const prevProject = rowIndex > 0 ? this.recordList[rowIndex - 1].project : null;
if (project === prevProject) {
// 当前项目与上一行项目相同,隐藏当前单元格
return [0, 0];
} else {
// 当前项目与上一行不同,计算合并行数
const spanCount = this.recordList.filter(item => item.project === project).length;
return [spanCount, 1]; // 合并 `spanCount` 行,列合并为 1
}
}
if (columnIndex === 1) {
// 合并 "小项" 列
const subitem = row.subitem;
const prevSubitem = rowIndex > 0 ? this.recordList[rowIndex - 1].subitem : null;
if (subitem === prevSubitem) {
return [0, 0];
} else {
const spanCount = this.recordList.filter(item => item.subitem === subitem).length;
return [spanCount, 1];
}
}
// 其他列不合并,返回默认值
return [1, 1];
},
}
};
</script>
<style lang="scss" scoped>
.record-manage-container {
padding: 20px;
.title{
font-size: 24px;
font-weight: bold;
}
}
</style>
分析
1. res.records.flat()
:将 records
中的二维数组扁平化为一维数组。例如:
const records = [
[{ id: 1 }, { id: 2 }],
[{ id: 3 }, { id: 4 }]
];
const flattened = records.flat();
console.log(flattened); // [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]
2. mergeCells()方法的实现逻辑