心心念念
念念不忘,必有回响!iview4.0终于出了合并单元格的功能,喜极而泣,最近的项目全是各种表格,正好有此需求,之前项目用的3.4.2版本,在iview官网上看到span-method功能,然后就升级升级升级!
链接: https://www.iviewui.com/components/table#GDBT.
源码: https://gitee.com/penny0906/blog-files/tree/master/reportTable.
基本思路
span-method对应的函数返回的是单元格占据的行列,然后就如果存在一个跟表格内容一一对应的行列的二维数组layout,根据当前参数rowIndex, columnIndex,返回layout[rowIndex][columnIndex],这样就方便多了,所有的代码都是为了得到这个layout数组!
实现合并
1.后台返回的数据一般长这样:
一个数组,每一项里包含key,value
2.期待的layout
我们想得到的layout长这样,一个布局数组
3.实现
代码片
.
handleSpan({ row, column, rowIndex, columnIndex }) {
// 合并单元格
return this.layout[rowIndex][columnIndex];
},
getLayOut() {
// 获取布局数组
// 得到一个跟布局数组结构一样的相对应的表格value值数组
const arr = [];
let columnsKey = this.getOrderColumnsKey(this.tableOptions.columns, []);
this.tableOptions.data.forEach(it => {
arr.push([]);
columnsKey.forEach(key => {
arr[arr.length - 1].push(it[key]);
});
});
// 得到一个普通的布局数组
this.layout = [];
arr.forEach(item => {
this.layout.push([]);
item.forEach(it => {
this.layout[this.layout.length - 1].push([1, 1]);
});
});
// 得到一个合并单元格布局数组
for (let i = 0; i < this.layout.length; i++) {
for (let j = 0; j < this.tableOptions.reportLength; j++) {
const target = this.layout[i][j];
if (target[0] * target[1] !== 0) {
// 向下合并
for (let k = i + 1; k < this.layout.length; k++) {
if (arr[i][j] === arr[k][j]) {
target[0] += 1;
this.layout[k][j] = [0, 0];
} else {
break;
}
}
// 向右合并
for (let k = j + 1; k < this.layout[i].length; k++) {
if (arr[i][j] === arr[i][k]) {
target[1] += 1;
this.layout[i][k] = [0, 0];
} else {
break;
}
}
}
}
}
},
getOrderColumnsKey(list, arr) {
// 获取多级columns平铺的key值,变为一维数组
list.forEach((it, index) => {
if (it.key) {
arr.push(it.key);
} else {
arr.push([]);
this.getOrderColumnsKey(it.children, arr[index]);
}
});
return arr.flat(Infinity);
}
补充:
1)this.tableOptions是我的表格配置项;
2)columnsKey 是当前表格显示的key值数组,从左到右,顺序必须对;不是后台返回的key值顺序,是前端页面显示的顺序!
因为我这个表头层级比较多,所以写了个getOrderColumnsKey方法把key值取出来了,可以参考;
3)this.tableOptions.reportLength这个参数是你需要几列做这个合并操作,就填几,我的表格只要前两列做合并,后面都是数值,不需要做合并了,我传的参数是2;
4)这个逻辑是字段的value值重复就会合并,让后台尽量给一个合适的结构,参考第一张图;
5)这个方法有一点需要注意,如果你第一组和第二组内容列有重复的地方,此处也会进行合并,如果希望每组内容自己独立,不合并别组内容,可以根据原数据自己定义一个以组为区别的新的数组,作为判断是否合并的依据数组,具体解决方法参考源码this.newData就是以groupName字段相互区别的新数组,如果没有此困扰,可以忽略这一条;
4.最终效果
5.希望对你有所帮助,菜鸡的第一篇博客记录,留爪!如有雷同想法,纯属巧合!