前言
本文代码使用vue2+element UI,通过给table
传入span-method
方法实现合并行或列
效果图
示例代码
后端返回数据格式如下
javascript
{
"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"
}
]
]
}
分析后端返回数据 :
records
是一个 二维数组, 而el-table
的data
属性通常期望的是 一维数组。所以需要将records中的二维数组 扁平化为一维数组,再赋值。
代码如下
javascript
<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>
分析
res.records.flat()
:将records
中的二维数组扁平化为一维数组。例如:
javascript
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 }]
- mergeCells()方法的实现逻辑
合并"项目"列 (
columnIndex === 0
):
- 判断当前行与上一行的项目 (
project
) 是否相同。- 如果相同,返回
[0, 0]
,表示隐藏当前单元格,因为它会被上一个单元格合并。- 如果不同,则计算相同项目的行数
spanCount
,返回[spanCount, 1]
,表示合并spanCount
行,列合并为 1。合并"小项"列 (
columnIndex === 1
):
- 判断当前行与上一行的小项 (
subitem
) 是否相同。- 如果相同,返回
[0, 0]
,隐藏当前单元格。- 如果不同,计算相同小项的行数
spanCount
,返回[spanCount, 1]
。默认情况:
- 对于其他列(比如类别、成绩、创造者等),不需要进行合并,直接返回
[1, 1]
表示不合并。