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

如何在Laravel导航菜单中展示分类-子分类层级结构

在Laravel中实现分类与子分类的导航菜单层级结构

嘿,这个需求我之前做项目的时候刚好碰到过,咱们一步步来搞定它~首先得提个小细节:你给的数据里id=1的分类parent_id是1,这会造成自引用循环哦,建议把顶级分类的parent_id改成0或者null,这样逻辑更通顺,下面我就按这个修正后的逻辑来给你方案哈

1. 给Category模型添加上关联关系

我们需要让模型能识别父分类和子分类的关联,打开你的App\Models\Category.php,添加以下代码:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    // 定义子分类关联:一个分类可以有多个子分类
    public function children()
    {
        return $this->hasMany(Category::class, 'parent_id');
    }

    // 可选:定义父分类关联,方便反向查询
    public function parent()
    {
        return $this->belongsTo(Category::class, 'parent_id');
    }
}

2. 在控制器里获取树形结构的分类数据

接下来要把扁平的分类数据转换成树形结构,方便视图渲染,这里提供两种方式,你可以按需选择:

方式一:预加载固定层级的子分类(适合层级确定的情况)

如果你的分类最多只有3层(比如顶级→二级→三级),可以直接用嵌套预加载:

namespace App\Http\Controllers;

use App\Models\Category;
use Illuminate\Http\Request;

class CategoryController extends Controller
{
    public function index()
    {
        // 获取所有顶级分类(parent_id=0),并预加载二级、三级子分类
        $categories = Category::where('parent_id', 0)
            ->with('children.children')
            ->get();

        return view('layouts.navigation', compact('categories'));
    }
}

方式二:递归生成完整树形结构(适合层级不确定的情况)

如果分类层级不固定,比如可能有四级、五级,那就用递归函数来构建树形数组:

namespace App\Http\Controllers;

use App\Models\Category;
use Illuminate\Http\Request;

class CategoryController extends Controller
{
    public function index()
    {
        $allCategories = Category::all();
        // 递归生成树形结构,默认从parent_id=0的顶级分类开始
        $treeCategories = $this->buildTree($allCategories);

        return view('layouts.navigation', compact('treeCategories'));
    }

    // 递归构建树形结构的辅助函数
    private function buildTree($categories, $parentId = 0)
    {
        $tree = [];
        foreach ($categories as $category) {
            if ($category->parent_id == $parentId) {
                // 递归查找当前分类的子分类
                $children = $this->buildTree($categories, $category->id);
                if ($children) {
                    $category->children = $children;
                }
                $tree[] = $category;
            }
        }
        return $tree;
    }
}

3. 在Blade视图里递归渲染导航菜单

最后一步就是把树形数据渲染成带层级的导航菜单,我们可以用Blade的@include实现递归渲染:

第一步:主视图中的导航容器

比如在你的布局文件resources/views/layouts/navigation.blade.php中:

<nav class="navbar">
    <ul class="main-menu">
        <!-- 循环顶级分类,调用子视图渲染每个分类项 -->
        @foreach($categories as $category)
            @include('partials.category-menu-item', ['category' => $category])
        @endforeach
    </ul>
</nav>

第二步:创建递归渲染的子视图

新建resources/views/partials/category-menu-item.blade.php,内容如下:

<li class="menu-item">
    <!-- 分类链接 -->
    <a href="{{ route('categories.show', $category->id) }}">{{ $category->title }}</a>

    <!-- 如果当前分类有子分类,递归渲染子菜单 -->
    @if($category->children->isNotEmpty())
        <ul class="sub-menu">
            @foreach($category->children as $child)
                @include('partials.category-menu-item', ['category' => $child])
            @endforeach
        </ul>
    @endif
</li>

这样不管你的分类有多少层级,都会自动递归渲染出来,最后你只需要给.main-menu、.sub-menu这些类加CSS样式,调整缩进、下拉效果就可以啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:35:32