前言
最近开发复杂表格,其中的合并处理比较难搞,分享两种合并的思路,如果帮到你了可以点个赞。
思路一
菜单分类、页面、子页面具有父子关系,表格合并只发生在菜单分类。
后端返回数据格式:普通的树状结构,主要由前端构造表格数据。
实现思路:
1. 以页面列为表格数据源,挂载父级(菜单分类)和子级(子页面);
2. 根据父级的children长度设置rowspan,并关联父级,因为要做勾选。
关于搜索:建议由后端实现,因为开发更简单,前端每次获取到数据时,重新执行表格合并即可。
关键代码:
// 列配置
columns: [
{
title: '菜单分类',
dataIndex: 'parentName',
key: 'parentName',
width: 150,
customCell: (record: any) => {
if (record.rowspan) {
return { rowSpan: record.rowspan }
} else {
return { rowSpan: 0 }
}
},
},
{ title: '页面', dataIndex: 'name', key: 'name', width: 150 },
{ title: '子页面', dataIndex: 'children', key: 'children' },
]
// 假设接口返回的是扁平数据,由code和parentCode组成树形结构
const rawData = data
// 排序
data = utils.commonSortArrayByField(data, 'sortNum')
// 转树
data = utils.handleTree(data, 'code', 'parentCode')
// 给树设置层级
data = utils.setTreeLevel(data)
// 转扁平
data = utils.treeToArr(data)
// 过滤出第二级
data = data.filter((item) => item.level === 2)
// 处理数据
data.forEach((item) => {
// 找到父级,根据父级的children长度设置rowspan
let parent = rawData.find((parent) => parent.code === item.parentCode)
// 关联父级
item.parent = parent
// 只给第一个子节点设置rowspan
if (parent?.children?.length && item.code === parent.children[0].code) {
item.rowspan = parent.children.length
// 设置父级名称
item.parentName = parent?.name
}
// 给所有子节点设置索引,从0开始
item.index = parent?.children?.findIndex((i) => i.code === item.code)
})
思路二
注意:红框只是一行,并不是三行,后端返回的数据是放在一个对象中的。
实现思路:
1. 先将后端数据转换成:[{…, actionNames: ['画边', '画边', '基牙'], …}]
2. 再获取数组项的类型和数量:actionNames: [{value: '画边', count: 2}, {value: '基牙', count: 1}]
3. 最后根据数量动态设置height:一个单元格的高度 * count
获取数组项的类型和数量:
function transform(arr) {
return arr.reduce((prev, cur) => {
let obj = prev.find((item) => item.value === cur);
if (obj) {
obj.count++;
} else {
prev.push({ value: cur, count: 1 });
}
return prev;
}, []);
}
console.log(transform(['a', 'a', 'b'])); // [{value: 'a', count: 2}, {value: 'b', count: 1}]