如何在Laravel中将分类查询结果按指定顺序拆分为5列布局
解决方案
你需要的纵向优先填充5列的需求完全可以通过Laravel Collection方法实现,原有代码报错核心是错误调用了模型实例的count()、has()等不存在的方法,同时嵌套循环逻辑存在逻辑偏差。
核心实现逻辑
纵向优先填充的本质是:
- 先计算每列需要放置的元素数量:总元素数 ÷ 列数 向上取整,15个元素5列的场景下每列3个
- 按顺序将元素先填满第一列,再填第二列,直到第五列
- 渲染时按行读取,每行依次取各列的对应位置元素即可得到你要的排列效果
完整实现代码
1. AppServiceProvider.php 代码
public function boot() { // 确保按id升序获取分类 $menus = Category::orderBy('id')->get(); $totalColumn = 5; // 固定5列布局 // 计算每列最多放多少个元素 $perColumn = (int)ceil($menus->count() / $totalColumn); // 拆分成分列的集合 $menuColumns = $menus->split($totalColumn); // 补全短列的空值,避免后续转置报错 $menuColumns = $menuColumns->map(function ($column) use ($perColumn) { return $column->pad($perColumn, null); }); // 转置为行集合,方便模板按行渲染 $menuRows = $menuColumns->transpose(); // 共享给所有视图 view()->share(compact('menus', 'menuRows')); }
2. Blade 模板代码
@foreach($menus as $menu) <div class="tab-pane fade {{ $loop->first ? 'show active' : '' }}" id="v-pills-{{ $menu->id }}" role="tabpanel" aria-labelledby="v-pills-{{ $menu->id }}-tab"> @foreach($menuRows as $row) <div class="row w-100 position-absolute"> @foreach($row as $columnItem) @if($columnItem) {{-- 跳过补位的空值 --}} <div class="col-xs-5"> <ul> <li> <a href="{{ $columnItem->path() }}" class=""> {{ $columnItem->id }} </a> <ul> @foreach($columnItem->getChild as $child) <li> <a href="{{ $child->path() }}" class=""> {{ $child->name }} </a> <ul> @foreach($child->getChild as $subChild) <li> <a href="{{ $subChild->path() }}" class=""> {{ $subChild->name }} </a> </li> @endforeach </ul> </li> @endforeach </ul> </li> </ul> </div> @endif @endforeach </div> @endforeach </div> @endforeach
低版本Laravel兼容方案
如果你使用的Laravel版本低于8.0,没有内置transpose()方法,可以使用以下兼容方案,无需修改AppServiceProvider,直接调整Blade模板逻辑即可:
@php $totalColumn = 5; $perColumn = (int)ceil($menus->count() / $totalColumn); @endphp @foreach($menus as $menu) <div class="tab-pane fade {{ $loop->first ? 'show active' : '' }}" id="v-pills-{{ $menu->id }}" role="tabpanel" aria-labelledby="v-pills-{{ $menu->id }}-tab"> @for($rowIndex = 0; $rowIndex < $perColumn; $rowIndex++) <div class="row w-100 position-absolute"> @for($colIndex = 0; $colIndex < $totalColumn; $colIndex++) @php $currentItem = $menus->get($rowIndex + $colIndex * $perColumn); @endphp @if($currentItem) <div class="col-xs-5"> <ul> <li> <a href="{{ $currentItem->path() }}" class=""> {{ $currentItem->id }} </a> <ul> @foreach($currentItem->getChild as $child) <li> <a href="{{ $child->path() }}" class=""> {{ $child->name }} </a> <ul> @foreach($child->getChild as $subChild) <li> <a href="{{ $subChild->path() }}" class=""> {{ $subChild->name }} </a> </li> @endforeach </ul> </li> @endforeach </ul> </li> </ul> </div> @endif @endfor </div> @endfor </div> @endforeach
内容的提问来源于stack exchange,提问作者user16277300
相关产品推荐
相关产品推荐

