Element UI 之 Table 树形数据合并行的实现

一、需求说明

Table 内容为树形结构,但需要合并收费项目重复列,具有子项的项目可展开和收起。如图:

二、遇到问题

1、表格数据格式

[{id: 1,name: '篮网',item: '投篮(%)',value: Number.parseInt(Math.random() * 100),children: [{id: 311,name: '詹姆斯·哈登',item: '投篮(%)',value: Number.parseInt(Math.random() * 100)}, {id: 312,name: '詹姆斯·哈登',item: '三分(%)',value: Number.parseInt(Math.random() * 100)}, {id: 313,name: '詹姆斯·哈登',item: '罚球(%)',value: Number.parseInt(Math.random() * 100)}]}, {id: 2,name: '篮网',item: '三分(%)',value: Number.parseInt(Math.random() * 100),children: [{id: 321,name: '詹姆斯·哈登',item: '投篮(%)',value: Number.parseInt(Math.random() * 100)}, {id: 322,name: '詹姆斯·哈登',item: '三分(%)',value: Number.parseInt(Math.random() * 100)}, {id: 323,name: '詹姆斯·哈登',item: '罚球(%)',value: Number.parseInt(Math.random() * 100)}]}, {id: 3,name: '篮网',item: '罚球(%)',value: Number.parseInt(Math.random() * 100),children: [{id: 31,name: '詹姆斯·哈登',item: '投篮(%)',value: Number.parseInt(Math.random() * 100)}, {id: 32,name: '詹姆斯·哈登',item: '三分(%)',value: Number.parseInt(Math.random() * 100)}, {id: 33,name: '詹姆斯·哈登',item: '罚球(%)',value: Number.parseInt(Math.random() * 100)}]}]

2、表格未合并列前

3、期待合并效果

4、实际合并效果(注意观察项目列是否正确)

5、造成原因

通过打印第一列渲染内容,发现表格树形结构项无论是否展开、是父节点还是子节点,都是顺序执行渲染。这样,Table 标签的 rowspan 或者 colspan 属性所执行的合并行或合并列,合并机制都是按照渲染内容顺序来执行的。则没法做到我们想要的先合并父节点,再合并子节点。

三、解决思路

1、为达到先合并父节点,再合并子节点效果,可将上文提供的数据转为以下数据格式(相同父节点列表中最后一项保留子节点数据)。

[{id: 1,name: '篮网',item: '投篮(%)',value: Number.parseInt(Math.random() * 100)}, {id: 2,name: '篮网',item: '三分(%)',value: Number.parseInt(Math.random() * 100)}, {id: 3,name: '篮网',item: '罚球(%)',value: Number.parseInt(Math.random() * 100),children: [{id: 31,name: '詹姆斯·哈登',item: '投篮(%)',value: Number.parseInt(Math.random() * 100)}, {id: 32,name: '詹姆斯·哈登',item: '三分(%)',value: Number.parseInt(Math.random() * 100)}, {id: 33,name: '詹姆斯·哈登',item: '罚球(%)',value: Number.parseInt(Math.random() * 100)}]}]


2、可这样一来,发现表格无法展开。但若添加 default-expand-all 则能看到展开项,但依然无法切换树形表格是否展开与收起,造成原因是因为父节点列表中第一项没有 children 数据。

3、所幸的是,Element UI 给我们提供了 toggleRowExpansion 方法,我们可以通过给数据打标识和调用 toggleRowExpansion 方法来实现树形表格的展开与收起。

四、Demo 演示及代码


在真正的业务中,后端给前端的数据更可能是具有相关标识的扁平化数据。本文代码中,也是从扁平化数组整合为符合操作需求的树形结构数据。

// mock.js
export const originTableData = [{ id: 1, parentId: 0, name: '篮网', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 2, parentId: 0, name: '篮网', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 3, parentId: 0, name: '篮网', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) },{ id: 31, parentId: 3, name: '詹姆斯·哈登', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 32, parentId: 3, name: '詹姆斯·哈登', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 33, parentId: 3, name: '詹姆斯·哈登', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) },{ id: 34, parentId: 3, name: '凯文·杜兰特', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 35, parentId: 3, name: '凯文·杜兰特', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 36, parentId: 3, name: '凯文·杜兰特', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) },{ id: 37, parentId: 3, name: '凯里·欧文', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 38, parentId: 3, name: '凯里·欧文', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 39, parentId: 3, name: '凯里·欧文', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) },{ id: 4, parentId: 0, name: '湖人', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 5, parentId: 0, name: '湖人', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 6, parentId: 0, name: '湖人', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) },{ id: 61, parentId: 6, name: '勒布朗·詹姆斯', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 62, parentId: 6, name: '勒布朗·詹姆斯', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 63, parentId: 6, name: '勒布朗·詹姆斯', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) },{ id: 64, parentId: 6, name: '安东尼·戴维斯', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 65, parentId: 6, name: '安东尼·戴维斯', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 66, parentId: 6, name: '安东尼·戴维斯', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) },{ id: 67, parentId: 6, name: '亚历克斯·卡鲁索', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 68, parentId: 6, name: '亚历克斯·卡鲁索', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 69, parentId: 6, name: '亚历克斯·卡鲁索', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) },{ id: 7, parentId: 0, name: '快船', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 8, parentId: 0, name: '快船', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 9, parentId: 0, name: '快船', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) },{ id: 91, parentId: 9, name: '保罗·乔治', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 92, parentId: 9, name: '保罗·乔治', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 93, parentId: 9, name: '保罗·乔治', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) },{ id: 94, parentId: 9, name: '科怀·伦纳德', item: '投篮(%)', value: Number.parseInt(Math.random() * 100) },{ id: 95, parentId: 9, name: '科怀·伦纳德', item: '三分(%)', value: Number.parseInt(Math.random() * 100) },{ id: 96, parentId: 9, name: '科怀·伦纳德', item: '罚球(%)', value: Number.parseInt(Math.random() * 100) }
]


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部