You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 8如何在服务端实现makeTree递归生成树形JSON结构

Laravel 8 服务端实现树形结构组装方案

你可以用两种方案实现和前端makeTree完全一致的效果,其中第一种完全对齐你原有的JS递归逻辑,第二种是Laravel框架原生的关联实现方式。


方案一:复刻前端递归逻辑(推荐,性能最优)

这个方案和你写的JS逻辑1:1对应,只需要把JS的数组操作换成Laravel集合的操作即可,仅需1次全量查询,性能不受树的层级影响。

实现逻辑

  1. 首先查询拿到全量的扁平节点数据
  2. 编写递归函数,逻辑和前端完全对齐:过滤指定父ID的节点,遍历每个节点递归挂载子节点
  3. 最后重置数组连续键,避免JSON序列化出现非预期的对象结构

代码示例

你可以直接把逻辑写在控制器方法中,也可以封装到模型的静态方法里复用:

<?php

namespace App\Http\Controllers;

use App\Models\MyTree;

class TreeController extends Controller
{
    public function getTree()
    {
        // 查询全量扁平节点数据
        $flatNodes = MyTree::all()->toArray();
        
        // 递归构建树,逻辑和前端JS完全一致
        $buildTree = function (array $nodes, $parentId = null) use (&$buildTree) {
            return collect($nodes)
                ->where('parent_id', $parentId) // 对应JS的filter逻辑:筛选当前父级下的直接子节点
                ->map(function ($node) use ($nodes, $buildTree) {
                    // 递归挂载子节点,对应JS的展开节点+children赋值
                    $node['children'] = $buildTree($nodes, $node['id']);
                    return $node;
                })
                ->values() // 重置数组键为连续数字索引,避免转JSON时变成对象
                ->toArray();
        };

        $tree = $buildTree($flatNodes);
        
        return response()->json($tree);
    }
}

这个方案输出的结构和你前端原来生成的结构完全一致,叶子节点的children默认是空数组,不需要额外处理。


方案二:基于Laravel模型关联递归加载

利用你已经定义好的children自关联,扩展一个递归关联,让Laravel自动帮你完成嵌套结构组装,代码更贴合框架原生写法。

实现逻辑

  1. 在MyTree模型中新增递归关联方法,实现无限层级的子节点预加载
  2. 查询根节点(parent_id为null)时,带上递归关联的预加载,直接返回结果即可

代码示例

首先修改MyTree模型,新增递归关联:

class MyTree extends Model
{
    // 原有代码保持不变...

    /**
     * 递归加载所有层级子节点
     */
    public function childrenRecursive()
    {
        return $this->children()->with('childrenRecursive');
    }
}

然后在控制器中直接查询返回:

public function getTree()
{
    $tree = MyTree::whereNull('parent_id')
        ->with('childrenRecursive') // 自动递归预加载所有层级子节点
        ->get()
        ->toArray();
    
    return response()->json($tree);
}

这个方案的缺点是查询SQL的数量和树的层级数相等(比如3层树会执行3条SQL),如果树的层级超过5层,性能会比方案一差,适合层级较浅的场景。


注意事项

  • 记得给数据库表的parent_id字段加索引,大幅提升大数据量下的查询和过滤速度
  • 如果需要自定义返回字段,查询时用select()指定字段即可,必须保留id、parent_id两个关联依赖字段
  • 两个方案输出的JSON结构和你前端原有makeTree的输出完全兼容,前端可以直接替换接口地址不需要改原有解析逻辑

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:48:54