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"
    },
   ...
]

页面效果如下

相关推荐
ZC跨境爬虫3 分钟前
跟着 MDN 学CSS day_7:(层叠优先级与继承)
前端·css·数据库·ui·html
Shadow(⊙o⊙)9 分钟前
qt信号和槽链接的接入与断开
开发语言·前端·c++·qt·学习
慕斯fuafua9 分钟前
JS——DOM操作
前端·javascript·html
微祎_18 分钟前
写给新手的 triton-inference-server-ge-backend:昇腾Triton推理服务后端到底是啥?
前端·人工智能·cann
烂不烂问厨房21 分钟前
两张图片拼接在一起中间有条白线
前端
掘金安东尼24 分钟前
浏览器跨域窗口通信技术调研:window.open 与 postMessage
前端
Highcharts.js2 小时前
缺失数据可视化图表开发实战|Highcharts创建人员出生统计面积图表示例
开发语言·前端·javascript·信息可视化·highcharts·图表开发
LaughingZhu9 小时前
Product Hunt 每日热榜 | 2026-05-21
前端·人工智能·经验分享·chatgpt·html
怕浪猫9 小时前
Electron 开发实战(一):从零入门核心基础与环境搭建
前端·electron·ai编程
小鹏linux10 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机