携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
平铺数据转换成树形数据
平铺数据转为树形数据,当平铺数据转为树形数据时,转化的关键点在于以下几点:
子节点的parentCode等于父节点的id
有相同parentCode的节点,为同一级且有同一个父节点
观察树结构发现,每一层都是一样的结构,因此可以使用递归实现。
<template>
<div>
<el-tree
:data="dataListTree"
show-checkbox
default-expand-all
node-key="id"
ref="tree"
highlight-current
:props="defaultProps"
>
</el-tree>
</div>
</template>
<script>
export default {
name: "treeComponent",
data() {
return {
// 平铺数据
dataList: [
{ id: "00", label: "一级菜单A", parentCode: null },
{ id: "00A", label: "二级菜单A", parentCode: "00" },
{ id: "00B", label: "二级菜单B", parentCode: "00" },
{ id: "00A01", label: "三级菜单甲", parentCode: "00A" },
{ id: "00A02", label: "三级菜单乙", parentCode: "00A" },
{ id: "00A03", label: "三级菜单丙", parentCode: "00A" },
{ id: "00B01", label: "三级菜单戊", parentCode: "00B" },
{ id: "00B02", label: "三级菜单戌", parentCode: "00B" },
],
dataListTree: [],
defaultProps: {
children: "children",
label: "label",
},
};
},
methods: {
// 定义方法将平铺数据转换成树形类型的数据,使用递归。
arrToTree(dataList, parentCode = null) {
// 定义结果数组
const res = [];
dataList.forEach((item) => {
if (item.parentCode === parentCode) {
// 这样每次都需要遍历整个数组,因此时间复杂度为 n*n
// const children = arrToTree(dataList, item.id)
// 往下递归时,每次数组的大小都在减小,每次都筛选掉父代元素,最终的时间复杂度为 n*logn
// 当箭头函数的函数体只有一个return语句时,可省略return和大括号{}
const children = this.arrToTree(
// 把已经匹配的父代元素筛选出去
dataList.filter((value) => value.parentCode !== parentCode),
// 父ID
item.id
);
if (children.length) {
res.push({ ...item, children });
} else {
res.push({ ...item });
}
}
});
return res;
},
myTree() {
this.dataListTree = this.arrToTree(this.dataList);
// console.log(this.dataListTree);
// 可将数据转换成JSON字符串形式
// console.log(JSON.stringify(tree, null, 2));
}
},
mounted() {
this.myTree();
},
};
</script>
<style lang="less" scoped>
</style>
树形数据递归遍历
当需要对树形数据进行修改时,可使用递归遍历该树形数据。
若接口返回树形数据node,使用createTree方法遍历该树形数据得到修改后的数据。
createTree方法
/**
* 将后端返回的树形结构转为前端能识别的树形结构
*/
createTree(node) {
// node为后端返回的树形数据
let treeNode = {
id: node.fileId,
label: node.dirName,
dataId: node.id,
parentFileId: node.parentFileId,
type: node.type,
allValue: node,
children: []
};
if (node.childList) {
node.childList.forEach((childNode) => {
treeNode.children.push(this.createTree(childNode));
});
}
return treeNode;
},
在element ui中,树形控件里面动态绑定:props="defaultProps",该方法就是改变了接口返回的属性名。
defaultProps: {
// children1为后端里面的属性名,映射为控件里面的children
// label1为后端里面的属性名,映射为控件里面的label
children: 'children1',
label: 'label1'
}