Laravel 10.x 中实现无限级分类的分页加载子分类,核心是按需异步加载直接子类并分页;推荐使用 path 字段法(如 "0001_0002")支持前缀查询与层级控制,或简化用 parent_id + paginate;前端通过 Ajax 请求 /categories/{id}/children 获取分页 JSON 数据并动态渲染。

在 Laravel 10.x 中实现无限级分类的「分页加载子分类」,核心思路是:不一次性展开全部层级,而是按需(如点击父类时)异步加载其直接子分类,并对这些子分类做分页。这通常用于后台分类管理树形列表或前端可展开的分类导航,兼顾性能与用户体验。
1. 数据结构:使用嵌套集(Nested Set)或路径字段(Path-based)
无限级分类推荐用 路径字段法(path),比递归查询更易分页。例如数据表加一个 path 字段(如 "0001"、"0001_0002"、"0001_0002_0003"),或用整数前缀(如 1、1.2、1.2.3)。
-
id、name、parent_id是基础字段 -
path字段存储祖先路径,支持前缀匹配查询子类 - 插入/移动节点时需更新 path(可用模型事件或服务类封装)
2. 查询某一级子分类并分页(关键逻辑)
假设当前点击的是 ID 为 $parentId 的分类,要查它的直接子分类并分页:
// 方式一:用 parent_id + 分页(最简单,适合深度不大、子类数量适中)
$children = Category::where('parent_id', $parentId)
->orderBy('sort', 'asc')
->paginate(10); // 每页10个子分类
若需支持「无限级但只展开一层 + 分页」,该方式足够高效且易于理解。
若用 path 法(适合超大分类树):
$parent = Category::find($parentId);
if ($parent && $parent->path) {
// 查直接子级:path = 'parent_path_*' 且 level = parent_level + 1
$children = Category::where('path', 'like', $parent->path . '_%')
->whereRaw('LENGTH(path) - LENGTH(REPLACE(path, "_", "")) = ?', [$parent->depth + 1])
->orderBy('path')
->paginate(10);
}
3. 前端配合:点击展开 → 发起 Ajax 请求 → 渲染分页子列表
前端不要预加载所有子树。给每个父节点加「展开按钮」,点击后:
- 发送 GET 请求:
/categories/{id}/children?page=1 - 后端返回分页 JSON(含
data、next_page_url、prev_page_url等) - 前端用 JS 动态插入子分类列表,并绑定「下一页」按钮事件
- 可配合加载状态、无更多提示等交互细节
示例响应结构:
{
"data": [...],
"links": {
"first": "...?page=1",
"last": "...?page=5",
"prev": null,
"next": "...?page=2"
},
"meta": {
"current_page": 1,
"last_page": 5,
"per_page": 10
}
}
4. 路由与控制器示例
路由(api.php):
Route::get('/categories/{id}/children', [CategoryController::class, 'children']);
控制器方法:
public function children(Request $request, $id)
{
$parent = Category::findOrFail($id);
<pre class="brush:php;toolbar:false;">$children = Category::where('parent_id', $id)
->orderBy('sort')
->paginate(10);
return response()->json($children);
}
如需支持搜索或排序参数,可在 where 后追加条件,如 ->when($request->search, fn($q) => $q->where('name', 'like', "%{$request->search}%"))。











