
本文介绍如何在 Laravel 中将数据库查询出的服务数据按 service_category 分类聚合,并在 Blade 模板中以“分类标题 + 对应服务列表”的结构清晰展示,推荐在控制器中预处理分组逻辑以提升可读性与性能。
本文介绍如何在 laravel 中将数据库查询出的服务数据按 `service_category` 分类聚合,并在 blade 模板中以“分类标题 + 对应服务列表”的结构清晰展示,推荐在控制器中预处理分组逻辑以提升可读性与性能。
在构建服务展示页面时,直接遍历原始服务集合(如 $services)虽可行,但难以实现“同类别归组、分类标题置顶”的语义化布局。Laravel 并未内置 Blade 原生分组指令(如 @groupby),因此最佳实践是在控制器中完成数据预处理——将扁平数组转换为以 service_category 为键、服务集合为值的嵌套关联数组。这既符合 MVC 职责分离原则,也避免在视图中混入复杂逻辑,提升代码可维护性与性能。
以下是优化后的完整实现方案:
✅ 控制器层:预分组 + 排序保障结构一致性
Laravel Cloud(cloud.laravel.com)。此技能用于处理所有 Laravel Cloud 请求,包括搜索和读取数据。只要任务涉及 Laravel Cloud,即使用此技能。
public function order_services()
{
// 使用 Query Builder 替代原始 SQL,更安全、可链式调用
$services = DB::table('services')
->select('id', 'service_name', 'service_category', 'service_price')
->orderBy('service_category') // 确保同类数据连续,便于分组阅读
->orderBy('service_name') // 同类内按名称排序,提升用户体验
->get();
// 按 service_category 分组:生成 ['Design' => [...], 'Development' => [...]]
$groupedServices = [];
foreach ($services as $service) {
$groupedServices[$service->service_category][] = $service;
}
return view('guests/services', [
'list' => $groupedServices
]);
}✅ Blade 模板层:语义化渲染分组结构
@foreach ($list as $category => $servicesInCategory)
<h2 class="mt-4 mb-3 text-primary">{{ ucfirst($category) }}</h2>
<ul class="list-group mb-5" id="category-{{ Str::slug($category) }}">
@foreach ($servicesInCategory as $service)
<!-- 类别标题项 -->
<li class="list-group-item d-flex justify-content-between align-items-center border border-danger">
<span style="font-size:24px; color:red">
<i class="bi bi-check-circle font-weight-bold"></i>
</span>
<span style="font-weight:bold">{{ $category }}</span>
<span><u><i class="bi bi-magic"></i></u></span>
</li>
<!-- 具体服务项 -->
<li class="list-group-item d-flex justify-content-between align-items-center">
<span class="product_name" style="font-size:24px; color:#870FD1">
<i class="bi bi-plus-circle"></i>
</span>
<span class="product_name"
data-price="{{ $service->service_price }}"
data-category="{{ $service->service_category }}">
{{ $service->service_name }}
</span>
<span class="text-success"><u>Available</u></span>
</li>
@endforeach
</ul>
@endforeach⚠️ 关键注意事项
- ID 唯一性:原模板中重复使用 id="service_category" 和 id="service_name" 会导致 HTML ID 冲突(ID 必须全局唯一)。建议改为 class 或动态 ID(如 id="service-{{ $service->id }}")。
- 性能考量:若服务量极大(如 >1000 条),可考虑使用数据库原生 GROUP BY 配合 JSON_AGG(PostgreSQL)或 GROUP_CONCAT(MySQL),但需权衡可移植性;中小规模数据推荐 PHP 分组,逻辑清晰易调试。
- 空类别防护:可在 Blade 中添加 @if(!empty($servicesInCategory)) 判断,避免空分组渲染。
-
SEO 与可访问性:
标题层级需与页面整体结构一致;建议为每个分类区块添加 aria-labelledby 提升屏幕阅读器支持。
通过控制器预分组 + Blade 清晰嵌套循环,你不仅能实现美观的分类展示效果,还能让代码更健壮、可测试、易扩展——例如后续增加「每类最多显示3项」或「折叠/展开交互」时,逻辑依然集中可控。

















