Tree 树形控件 平铺数据转树状数据

问题

当我们使用element-ui的树形组件的时候,我们发现组件需要data里的数据是一种层层嵌套的树状结构

但是一般发送请求后服务器返回的数据是平铺数据

平铺数据是一种线性结构,所有的数据都存储在一个平等的层次中,没有明显的层级关系。

示例数据如下

javascript 复制代码
[
    {
        "id": 1,
        "name": "组织架构",
        "description": "组织架构",
        "type": 1,
        "code": "department",
        "pid": 0,
        "enVisible": "1",
    },
    {
        "id": 2,
        "name": "角色管理",
        "description": "角色管理菜单",
        "type": 1,
        "code": "role",
        "pid": 0,
        "enVisible": "1"
    },
    ...
    {
      "id": 1606,
      "name": "子权限",
      "description": "123123",
      "type": 2,
      "code": "123",
      "pid": 1,
      "enVisible": "1"
}
]

我们要将平铺数据转换为树状数据

树状数据是一种分层结构,数据以层级关系的形式组织,每个节点可以包含一个或多个子节点。

这个时候我们可以利用函数将平铺数据转换为树状数据,从而达到组件的数据要求

在上面的示例中,数据的父子关系通过唯一的 id 字段和其他对象中的 pid 字段的对应来进行识别。具体而言,当一个对象的 id 值等于另一个对象的 pid 值时,这两个对象就存在父子关系。

例如:一个对象的id为1,另一个对象pid为1,那么前者就是后者的父亲,需要将后者加到前者对象中

解决方法

以Vue为例,这个时候我们可以去utils工具箱文件夹中创建一个工具例如transformListToTree的方法来进行转换

javascript 复制代码
// 转树形结构的递归函数
export function transformListToTree(arr, id) {
  // 存储树状结构的数组
  const list = [];

  // 遍历平铺的数据数组
  arr.forEach((item) => {
    // 如果当前元素的父级标识符(pid)等于传入的父级标识符(id)
    if (item.pid === id) {
      // 递归调用函数,查找当前元素的子节点
      const tmp = transformListToTree(arr, item.id);

      // 如果当前元素有子节点,将子节点赋值给当前元素的 children 属性
      if (tmp.length > 0) {
        item.children = tmp;
      }

      // 将当前元素添加到存储树状结构的数组中
      list.push(item);
    }
  });

  // 返回存储树状结构的数组
  return list;
}

如何使用

在组件中使用transformListToTree方法

javascript 复制代码
<template>
  <el-tree
    ref="treeRef"
    :data="permisstionList"
    :props="defaultProps"
    show-checkbox
    default-expand-all
    :expand-on-click-node="false"
    check-strictly
    node-key="id"
  />
</template>

<script>
import { transformListTree } from '@/utils/transform';

export default {
  data() {
    return {
      // 平铺数据
      flatData: [
        // ... 平铺数据数组
      ],
      // 转换后的树状数据
      permisstionList: [],
      // Element UI 树形组件的 props 配置
      defaultProps: {
        // ... 具体配置项
        children: 'children', // 子节点属性名
        label: 'name' // 节点文本属性名
      },
    };
  },
  created() {
    // 在组件创建时进行数据转换
   this.permisstionList = transformListToTree(this.flatData, 0)
  },
};
</script>

最终结果

转换后的数据

javascript 复制代码
[
    {
        "id": 1,
        "name": "组织架构",
        "description": "组织架构",
        "type": 1,
        "code": "department",
        "pid": 0,
        "enVisible": "1",
        "children": [
            {
                "id": 1606,
                "name": "子权限",
                "description": "123123",
                "type": 2,
                "code": "123",
                "pid": 1,
                "enVisible": "1"
            }
        ]
    },
    {
        "id": 2,
        "name": "角色管理",
        "description": "角色管理菜单",
        "type": 1,
        "code": "role",
        "pid": 0,
        "enVisible": "1"
    },
   ...
]

页面效果如下

相关推荐
多多米100540 分钟前
初学Vue(2)
前端·javascript·vue.js
柏箱1 小时前
PHP基本语法总结
开发语言·前端·html·php
新缸中之脑1 小时前
Llama 3.2 安卓手机安装教程
前端·人工智能·算法
hmz8561 小时前
最新网课搜题答案查询小程序源码/题库多接口微信小程序源码+自带流量主
前端·微信小程序·小程序
看到请催我学习1 小时前
内存缓存和硬盘缓存
开发语言·前端·javascript·vue.js·缓存·ecmascript
blaizeer2 小时前
深入理解 CSS 浮动(Float):详尽指南
前端·css
编程老船长2 小时前
网页设计基础 第一讲:软件分类介绍、工具选择与课程概览
前端
编程老船长2 小时前
网页设计基础 第二讲:安装与配置 VSCode 开发工具,创建第一个 HTML 页面
前端
速盾cdn2 小时前
速盾:网页游戏部署高防服务器有什么优势?
服务器·前端·web安全
小白求学12 小时前
CSS浮动
前端·css·css3