Tree树形控件中平铺数据转换为树形数据和递归遍历树形数据

399 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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' 
}