背景:
需求是呈现一个表格,根据操作人跟操作时间是否相同来进行合并行数据
数据结构:
经过跟后端的同事商量,需要在每一行数据中返回rowSpanNum的值,前端在column中根据值来判断是否满足合并行(没有合并行是rowSpanNum值是1,有合并行时,第一行的值大于1,接下来的几行值是null
[
{
...,
rowSpanNum: 1,
},
{
...,
rowSpanNum: 3,
},
{
...,
rowSpanNum: null,
},
{
...,
rowSpanNum: null,
},
{
...,
rowSpanNum: 1,
},
]
前端处理column:
在column的render里面,我们可以定义一个obj对象,给obj对象的rowSpan属性进行赋值处理,再将obj返回即可
const columns = [
{
title: '数量',
dataIndex: '数量',
width: '80px',
align: 'right'
},
{
title: '日期',
dataIndex: '日期',
width: '90px'
},
{
title: '备注',
dataIndex: '备注',
},
{
title: '操作人',
dataIndex: 'createName',
width: '80px',
render: (text, record, index) => {
const obj = {
children: isShowPopover(text),
props: {
},
};
if(record.rowSpanNum){
obj.props.rowSpan = record.rowSpanNum;
}else{
obj.props.rowSpan = 0;
}
return obj;
},
},
{
title: '操作时间',
dataIndex: 'createTime',
width: '140px',
render: (text, record, index) => {
const obj = {
children: text,
props: {
},
};
if(record.rowSpanNum){
obj.props.rowSpan = record.rowSpanNum;
}else{
obj.props.rowSpan = 0;
}
return obj;
},
},
]
效果如图:
存在问题:antd针对table的最后一个tr做了border-bottom: 0;的处理,但是由于合并的行恰好能合并到table的最后一行,但是本身不属于最后一个tr,所以不具有该属性,导致td本身的border-bottom跟table的boder-bottom双重渲染。(好像antd的官网的table并不会出现这个问题,估计是公司在封装table组件的时候出现了问题)
解决方法:
定义一个方法,接收整个list跟当前行的index,通过index截取剩下的list,赋值给newArr数组,for循环newArr数组,判断接下来的元素是否还存在rowSpanNum有值的行信息,如果有,则保持当前td的borderBottom值,如果没有,则当前td的borderBottom为'none'
在column的中运用改方法修改style即可
borderBottomFunc = (List, currentIndex) => {
let newArr = List.slice(currentIndex+1)
for(let i=0; i<newArr.length; i++){
if(newArr[i].rowSpanNum){
return ''
}
}
return 'none'
}
// 修改column
{
title: '操作人',
dataIndex: 'createName',
width: '80px',
render: (text, record, index) => {
const obj = {
children: isShowPopover(text),
props: {
style: {
borderBottom: this.borderBottomFunc(List, index)
}
},
};
if(record.rowSpanNum){
obj.props.rowSpan = record.rowSpanNum;
}else{
obj.props.rowSpan = 0;
}
return obj;
},
},
{
title: '操作时间',
dataIndex: 'createTime',
width: '80px',
render: (text, record, index) => {
const obj = {
children: isShowPopover(text),
props: {
style: {
borderBottom: this.borderBottomFunc(List, index)
}
},
};
if(record.rowSpanNum){
obj.props.rowSpan = record.rowSpanNum;
}else{
obj.props.rowSpan = 0;
}
return obj;
},
},