el-table 合并行 且 序号保持自增
整体思路:
合并表格的行,在获取数据的同时把遍历表格数据进行排序(由于el-table只能合并相邻两行,因此要先进行排序),排序后遍历表格数据,通过以用户id或者其他想要合并的条件进行判断;
合并行:
在data()中新加colmap:[],每次遍历时把数据的下标存入colmap[]中,以行的下标为key,把每行需要合并的行数为value,遍历时判断这一次的数据和上一次数据中的用户id是否相同,当然也可以把其他字段当作判断标准,如果相同则把colmap中对应下标的值加一,否则把当前数据下标存入colmap[]中,初始值为0,合并行时用每行数据的下标取当前要合并的行数返回给eltable;
序号自增:
在data()中新建indexNum[],在构建合并行所需的工具数据时,规则同合并行,如果符合合并规则indexNum[]对应下标的值等同于上一行的值,如果不符合则加一。
后面是代码部分
页面部分:
objectSpanMethod为合并表格行的方法
<el-table
size="mini"
:data="tableData"
:height="TableHeight"
border
v-loading="loadingShow"
element-loading-text="数据正在加载中..."
:span-method="objectSpanMethod"
style="margin: 30px ; "
:header-cell-style="{ 'background-color': '#696da6', 'color': '#fff'}">
序号列
通过设置:index来设置自增,indexMethod为序号自增方法
<el-table-column v-if="tableData.length>0?true:false" label="序号" type="index" align="center" :index="indexMethod"/>
数据等js部分:
数据:
data(){
returen {
colmap: [], //行的集合
pos: 0, //colmap下标索引
indexNum: [], //序号集合
tableData: [
{
"deptName": "建工系",
"isLeaved": false,
"teacherName": "花荣",
"clock_time": "17:08:20",
"isHoliday": false,
"clock_date": "2021-12-09",
"isEvectioned": false,
"batch_name": "中",
"clock_type": "come",
"userid": "1",
"exception_name": "迟到",
"name": "花荣",
"id": null,
"userCode": "d69a8a5c524bb4ea89b928ebfdb96182"
},...
// (此处略去重复数据)
{
"deptName": "江湖系",
"isLeaved": false,
"teacherName": "金峰",
"isHoliday": false,
"isEvectioned": false,
"batch_name": "早",
"clock_type": "come",
"userid": "5",
"exception_name": "缺卡",
"name": "金峰",
"id": null,
"userCode": "500"
},...
// (此处略去重复数据)
], //表格数据
}
}
重新排序的方法(最好用的方法就是写注释的方法,哈哈):
/**
* @param lists 数组
* @description 由于eltable合并行或列只能合并相邻的,因此对tabledata数据重新排序
* */
sortList(lists){
return lists.sort((a, b) => {
return a['name'].localeCompare(b['name']) // grapheme为字母对应的属性名
})
},
构建筛选合并行的工具数据,同时构建序号自增工具数据
/**
* @param tabledata 表格数据
* @description 通过用户id来判断是否需要合并行
* */
formatMergeObj(tabledata){
this.colmap=[]
//因为担心直接用遍历时的key会有问题,新建contactDot来保存tabledata的下标
let contactDot=0;
let checknum=0;
this.indexNum=[];
for (let index in tabledata) {
//初始默认合并行数都为1
if (index === '0') {
this.colmap.push(1)
this.indexNum.push(checknum)
}else {
//如果和上一行相同则对应colmap中要合并的行数加一
if (tabledata[index].userid === tabledata[index - 1].userid) {
this.colmap[contactDot]+=1
this.colmap.push(0)
}else {
checknum+=1;
contactDot=index
this.colmap.push(1)
}
this.indexNum.push(checknum)
}
}
console.log("重新筛选数据")
},
合并行的方法:
/**
* @param row 行的数据
* @param column 列的数据
* @param rowIndex 行下标
* @param columnIndex 列下标
* @return 返回需要合并的行列下标
* @description 合并行
* */
objectSpanMethod({row, column, rowIndex, columnIndex}) {
//这里合并前三列
if (columnIndex <= 3) {
if (this.colmap[rowIndex]) {
return {
rowspan: this.colmap[rowIndex], //合并的行数
colspan: 1 //合并的列数0不显示
};
} else {
//返回0 0代表不显示
return {
rowspan: 0,
colspan: 0
}
}
}
},
序号自增方法:
/**
* 序号
* @param index 下标
* @returns {*}
* @description 返回对应行的序号
*/
indexMethod(index) {
return (this.ipagination.current - 1) * this.ipagination.pageSize + parseInt(this.indexNum[index]+1 )
},
踩过的坑:
- 由于合并行只能合并相邻的,因此需要对数据进行排序,如果实际情况的原始数据顺序不允许改变则不用排序
- 合并行返回值要明白什么含义,0 0是不显示,1 1才是显示
- 序号自增问题原先打算在indexMethod()中通过对data()中的indexNum:0 进行自增,但是发现el-table在渲染表格过程中发生死循环明,打印输出查看index,发现会输出两边,但是想不通即使两边也不至于导致死循环,后来网上查资料得知:
控制台显示el-table的render中无限循环,这段代码是一个递归调用来渲染层级表头的,每次会调用两次render函数。每次调用都会触发insertColumn, 这个函数对indexNum自增后,又导致table的render的执行,就这样死循环下去了。
(感谢https://blog.csdn.net/txyzqc/article/details/116460805给的思路)