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