react+antd+dva table动态合并行
简介
id | 描述 |
---|---|
1 | 不同内容1 |
1 | 不同内容2 |
需求是根据某一列例如id列两行都是1 那就将1合并为一行显示。
下面是主要代码段,由于项目是用react+antd 封装过的table表格,就直接写render中的代码了,antd的table中列column的render配置可查询官网。
思路
1、要求列表所有行的值要先进行排序,此处省略代码,也可后端排好序返回。
2、循环取出要合并的列的所有的行的值放到数组中,例如得到的数组是[14ab,14ab,14ab,15,15,16c,a17,m18],说明该列相同的值是:14ab重复3次即合并3行 ,15重复两次合并2行,其余行不合并。
3、由于已经排好序所以只要知道每行重复的次数 即每行需要合并多少行即可。我又做了一次筛选取得了每行重复次数的数组,即[3,2,1,1,1]
4、由于antd中table行合并的规则是 如果第一行合并2行,那第二行的rowSpan需要为0,因此我想把为0的行塞到次数的数组中,我又做了一次循环得到了[3,0,0,2,0,1,1,1]
5、将table的每一行rowspan的值依次设为 3,0,0,2,0,1,1,1即可
// columns的配置可查询antd官网table的行合并,我直接写render
render: {
id (text, row, ui,s) { //这里是项目中封装的render,参数可能与官网不太相同,但意思都是一样的,id代表id列,text为当前行的值,row为当前行,ui可以理解为全局this,可调用外部方法, s为当前行的index值
// 循环id列所有行的值
const{ props: { config: { data: { list } } } } = ui;
let arr = [];
list.map((item,i)=>{
arr.push(item.id);
})
// 取到每行重复的次数,下列方法可以查询下各自函数的意思
let map = arr.reduce((m,x)=> m.set(x, (m.get(x) || 0) + 1), new Map());
let newMapp = Array.from(map.values()) // 取出次数
const obj = {
children: text,
props:{}
}
// 循环塞0
let temp = '';
newMap.forEach((item,i)=>{
temp += item;
if ( item > 1 ) {
for ( let k = 0; k < item-1; k++) {
temp += '0
}
}
})
temp = temp.split(''); // 得到塞好0的数组
obj.props.rowSpan =Number(temp[s]) // 给每行设置rowSpan
}
}
以上是循环给每一行添加rowSpan的代码段,有些代码逻辑可能不是很清晰,我也在探索中,希望各位大神路过也指点一二。
另外一种写法:
render: {
id (text, record, ui, s) { // 这里参数与上同样,ui相当于是全局this
const { props: { ipState: {data: {list}} } } = ui; // 获取列表list数据;
let v4len = 0;
let v6len = 0;
list.map(item => {
if(item.id == '4') {
v4len++;
}else if (item.id == '6') {
v6len++;
}
})
const obj = {
children: text == '4' ? 'IPv4': ‘IPv6’,
props:{}
}
if ( s== 0 && v4len != 0){
obj.props.rowSpan = v4len;
} else if (s < = v4len-1) {
obj.props.rowSpan = 0;
} else if (s == v4len) {
obj.props.rowSpan = v6len;
} else if (s > v4len && s< (v6len)+(v4len)) {
obj.props.rowSpan = 0;
obj.props.colSpan = 0;
};
return obj;
}
}