[js] 两种表格合并处理思路

315 阅读2分钟

前言

最近开发复杂表格,其中的合并处理比较难搞,分享两种合并的思路,如果帮到你了可以点个赞。

思路一

image.png

菜单分类、页面、子页面具有父子关系,表格合并只发生在菜单分类。

后端返回数据格式:普通的树状结构,主要由前端构造表格数据。

实现思路:

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)
})

思路二

image.png 注意:红框只是一行,并不是三行,后端返回的数据是放在一个对象中的。

实现思路:

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}]