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

Laravel中如何在下拉选框显示带层级缩进的多级分类列表

实现多级分类下拉选框的层级缩进显示

你当前的代码只能处理一级子分类的缩进,要实现多级(比如孙分类、曾孙分类)的动态缩进,我们可以通过递归遍历分类树来生成带层级前缀的分类列表,下面是具体的实现步骤:

先提个小问题:你的数据库表结构里分类名称是title,但Model的$fillable里写的是name,这会导致字段不匹配,记得把Model里的name改成title(或者把表字段改成name,保持统一),不然会读取不到分类名称;另外表结构里的slug字段,你Model里的getRouteKeyName()写的是url,也要同步修正哦。


步骤1:在Category模型中添加递归生成带缩进分类的方法

我们可以写一个静态方法,递归遍历所有分类,根据层级动态添加短横线缩进:

class Category extends Model {
    protected $primaryKey = 'cid';
    protected $table = 'categories';
    // 修正fillable字段,和表结构保持一致
    protected $fillable = array('title','slug','image','status','parent_id');
    
    function getRouteKeyName() {
        return 'slug'; // 和表结构的slug字段对应
    }
    
    public function parent() {
        // 修正关联的命名空间,根据你的实际项目路径调整
        return $this->belongsTo(Category::class, 'parent_id');
    }
    
    public function children() {
        return $this->hasMany(Category::class, 'parent_id','cid');
    }
    
    // 递归生成带缩进的分类列表
    public static function getIndentedCategories($parentId = 0, $indent = '') {
        // 获取当前父分类下的所有子分类
        $categories = self::where('parent_id', $parentId)->get();
        $result = [];
        
        foreach ($categories as $category) {
            // 拼接缩进和分类标题,存入结果数组
            $result[] = [
                'cid' => $category->cid,
                'title' => $indent . $category->title,
                'parent_id' => $category->parent_id
            ];
            
            // 递归处理子分类的子分类,每往下一层,缩进多一个'-'
            $result = array_merge($result, self::getIndentedCategories($category->cid, $indent . '-'));
        }
        
        return $result;
    }
}

步骤2:修改Controller获取处理好的分类数据

在你的edit方法里,调用上面的静态方法,直接拿到带缩进的分类列表:

public function edit($id) {
    // 调用静态方法获取带层级缩进的分类数组
    $data = Category::getIndentedCategories();
    $item = Category::find($id);
    return view('admin.category.edit', compact('item', 'data'));
}

步骤3:修改View渲染下拉选框

现在视图里不需要再判断parent_id了,直接遍历处理好的数组即可:

<select name="parent_id">
    <!-- 可选:添加"无父分类"的选项 -->
    <option value="0" {{ $item->parent_id == 0 ? 'selected' : '' }}>无父分类</option>
    
    @foreach($data as $category)
        <option value="{{ $category['cid'] }}" {{ $category['cid'] == $item->parent_id ? 'selected' : '' }}>
            {{ $category['title'] }}
        </option>
    @endforeach
</select>

效果说明

这样处理后,你的下拉选框就会按照层级显示缩进,完全符合你给出的示例:

无父分类
Furniture
-Table
--Sidetable
---Designer Table
---Simple Table
-Sofa
-Chair
-Doors

如果想调整缩进的样式(比如用--代替-作为每层的缩进),只需要修改递归方法里的$indent . '-'为$indent . '--'即可。

另外,如果你的分类层级非常深,递归可能会有轻微的性能影响,但一般电商或内容系统的分类层级不会超过3-4层,所以完全不用担心。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 11:17:31