表格动态合并行
在日常的中后台工作中,表格合并是个很常见的需求。本文实现了一种表格合并的方案,让你不再为表格合并的开发而发愁,提升你的工作效率。
vue页面
<template>
<div style="width: 800px">
<sg-table :data="tableData" stripe border :span-method="arraySpanMethod">
<sg-table-column prop="class" label="班级"></sg-table-column>
<sg-table-column prop="name" label="姓名"></sg-table-column>
<sg-table-column prop="course" label="科目"></sg-table-column>
<sg-table-column prop="score" label="成绩"></sg-table-column>
</sg-table>
</div>
</template>
<script>
import mergeCell from "@/utils/mergeCell";
export default {
data() {
return {
tableData: [
{
class: "class1",
name: "王小虎",
course: "英语",
score: "88",
},
{
class: "class1",
name: "王小虎",
course: "英语",
score: "90",
},
{
class: "class1",
name: "王小虎",
course: "数字",
score: "75",
},
{
class: "class1",
name: "李明",
course: "英语",
score: "88",
},
{
class: "class1",
name: "李明",
course: "语文",
score: "90",
},
{
class: "class1",
name: "李明",
course: "数字",
score: "75",
},
{
class: "class2",
name: "王小虎",
course: "英语",
score: "88",
},
{
class: "class2",
name: "王小虎",
course: "语文",
score: "90",
},
{
class: "class2",
name: "王小虎",
course: "数字",
score: "75",
},
{
class: "class2",
name: "李明",
course: "英语",
score: "88",
},
{
class: "class2",
name: "李明",
course: "语文",
score: "90",
},
//........ 过长省略
],
//合并单元格
colNameArray: ["class", "name", "course"], //需要合并的列数组 [字段名1,字段名2,字段名2,...]
mergeArray: [], //计算合并行的数组
};
},
created() {
this.merge(this.tableData);
},
methods: {
merge(data) {
this.mergeArray = mergeCell(this.colNameArray, data);
},
arraySpanMethod({ rowIndex, columnIndex }) {
if (columnIndex < this.mergeArray.length) {
const _row = this.mergeArray[columnIndex][rowIndex];
const _col = _row > 0 ? 1 : 0; //如果被合并了_row=0则它这个列需要取消
return {
rowspan: _row,
colspan: _col,
};
}
},
},
};
</script>
再封装一个方法mergeCell在utils中
let colNumArray = []; // 每一列需要合并的行数数组
let colPosIndexArray = []; // 记录需要合并的列的位置
/**
* 数据初始化
* @param {需要合并的列数,即 字段名数组的长度 colNameArrayParam.length} colNum
*/
function initMerge(colNum) {
(colNumArray = []), (colPosIndexArray = []);
for (let i = 0; i < colNum; i++) {
colNumArray.push([1]); // 初始化第一行
colPosIndexArray.push([0]);
}
}
/**
* 合并处理
* @param {需要合并的字段名数组} colNameArrayParam
* @param {用来合并的源数据} dataParam
*/
const colNumberMergeCount = function (colNameArrayParam, dataParam) {
for (let i = 0; i < dataParam.length; i++) {
//遍历每一条数据
if (i == 0) {
initMerge(colNameArrayParam.length); //初始化第一行
} else {
let isAnd = true; // 记录必须前面的列合并才能合并当前列 如第3列合并 必须第1、2列也要合并
for (let j = 0; j < colNameArrayParam.length; j++) {
//遍历需要合并的列,计算合并的行数
if (isAnd && dataParam[i][colNameArrayParam[j]] === dataParam[i - 1][colNameArrayParam[j]]) {
//判断是否和上一列内容相同
colNumArray[j][colPosIndexArray[j]] += 1; // 如相同 则+1 表示合并的行数,
colNumArray[j].push(0); // 再push新的一行为0,表示这一行被合并
isAnd = true; // 记录并且关系
} else {
isAnd = false; // 如果不相同,刚之后的全都不合并
colNumArray[j].push(1); //push新行 默认为1
colPosIndexArray[j] = i; //更新计算合并行数的位置,如 从第1行开始计算,如果一直相同位置不变,后面一直push新行为0,反之,没有合并刚更新位置+1,从下一行开始计算合并
}
}
}
}
console.log(colNumArray);
return colNumArray; //返回合并处理后的数据
};
export default colNumberMergeCount;