js将有父子关系的数据转换成树形结构数据

本文介绍如何将接口返回的具有父子关系的数组转换为树形结构,适用于使用iview等UI库的树形组件。提供了一段实现代码,并提到该方法已在多个页面复用,可适应不同属性名的父子ID。作者欢迎分享更简便的方法以促进学习交流。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接口返回的数据是像allRes这样的数组:

let allRes = [
  {
    resourcesId: 4,
    resName: "删除角色",
    resParentId: 2
  },
  {
    resourcesId: 3,
    resName: "编辑角色",
    resParentId: 1
  },
  {
    resourcesId: 2,
    resName: "设置权限",
    resParentId: 1
  },
  {
    resourcesId: 5,
    resName: "添加用户",
    resParentId: 4
  },
  {
    resourcesId: 6,
    resName: "更新用户",
    resParentId: 4
  },
  {
    resourcesId: 7,
    resName: "删除用户",
    resParentId: 6
  },
  {
    resourcesId: 8,
    resName: "重置密码",
    resParentId: 3
  },
  {
    resourcesId: 9,
    resName: "添加地区",
    resParentId: 5
  },
  {
    resourcesId: 10,
    resName: "编辑地区",
    resParentId: 6
  }
];

在项目中我是用iview的树形组件所以需要转换成树形结构,以下是实现代码


let arr = toTreeData(allRes);

function toTreeData(data) {
  let resData = data;
  let tree = [];

  for (let i = 0; i < resData.length; i++) {
    if (resData[i].resParentId === 1) {
      let obj = {
        id: resData[i].resourcesId,
        text: resData[i].resName,
        children: []
      };
      tree.push(obj);
      resData.splice(i, 1);
      i--;
    }
  }
  run(tree);
  function run(chiArr) {
    if (resData.length !== 0) {
      for (let i = 0; i < chiArr.length; i++) {
        for (let j = 0; j < resData.length; j++) {
          if (chiArr[i].id === resData[j].resParentId) {

            let obj = {
              id: resData[j].resourcesId,
              text: resData[j].resName,
              children: []
            };
            chiArr[i].children.push(obj);
            resData.splice(j, 1);
            j--;
          }
        }
        // console.log(chiArr[i].children);
        run(chiArr[i].children);
      }
    }
  }
  return tree;
}

因为在多个页面中有用到,但是对应的id,和parent id 的属性名称是不一样的,所以封装了一下

function toTreeData (data, attributes) {
  let resData = data;
  let tree = [];

  for (let i = 0; i < resData.length; i++) {
    if (resData[i].resParentId === attributes.rootId) {
      let obj = {
        id: resData[i][attributes.id],
        title: resData[i][attributes.name],
        children: []
      };
      tree.push(obj);
      resData.splice(i, 1);
      i--;
    }
  }
  run(tree);
  function run(chiArr) {
    if (resData.length !== 0) {
      for (let i = 0; i < chiArr.length; i++) {
        for (let j = 0; j < resData.length; j++) {
          if (chiArr[i].id === resData[j][attributes.parentId]) {
            let obj = {
              id: resData[j][attributes.id],
              title: resData[j][attributes.name],
              children: []
            };
            chiArr[i].children.push(obj);
            resData.splice(j, 1);
            j--;
          }
        }
        run(chiArr[i].children);
      }
    }
  }

  return tree;

}

调用:

let data = allRes;
// 属性配置信息
let attributes = {
      id: 'resourcesId',
      parentId: 'resParentId',
      name: 'resName',
      rootId: 1
  };
let treeData = toTreeData(data, attributes);

格式化后的

[
    {
      id: 3,
      title: "重置密码",
      children: []
    },
    {
      id: 2,
      title: "设置权限",
      children: [
        {
          id: 4,
          title: "删除角色",
          children: [
            {
              id: 5,
              title: "添加用户",
              children: [
                {
                  id: 9,
                  title: "添加地区",
                  children: []
                }
              ]
            },
            {
              id: 6,
              title: "更新用户",
              children: [
                {
                  id: 7,
                  title: "删除用户",
                  children: []
                },
                {
                  id: 10,
                  title: "编辑地区",
                  children: []
                }
              ]
            }
          ]
        }
      ]
    }
  ]

因为个人的知识积累有限,应该还有更简便的方法,如果你有更好的方法可以告诉我,大家可以相互学习交流。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值