
本文详解如何在 laravel 项目中正确实现“按分类(如 fabrikasi、konstruksi 等)分别获取并展示最多 10 张作品图”,解决因错误使用 `take(10)` 或循环逻辑缺陷导致的图片不显示问题。
在构建企业官网或作品集页面时,常需将作品(Portfolio)按业务类别(如“Fabrikasi”“Konstruksi”“Repair”“Lainnya”)分组展示,并严格限制每类仅显示最新 10 张图。你当前遇到的问题——take(10) 在控制器中看似生效,但在 Blade 中仍无法正确渲染对应分类的图片(例如新增第 11 张 fabrikasi 图后,该分类反而只显示 3 张),根本原因在于:你在 Blade 中仍遍历了全部 $portfolios,却用 $loop->iteration 错误地判断全局序号,而非当前分类内的序号——这会导致“只要总序号超过 10,后续所有分类图片均被跳过”。
✅ 正确做法是:控制器按分类预查询、预截取;Blade 中直接遍历对应分类集合。
✅ 控制器优化(推荐简洁写法)
避免重复书写多个 where()->latest()->take(10)->get(),可统一处理:
// app/Http/Controllers/LandingController.php
public function landing()
{
$numbers = Number::get();
$testimonials = Testimonial::get();
$clients = Client::get();
// 定义分类映射(数据库中 category 字段值 → 前端 class 过滤器名)
$categories = [
'fabrikasi' => 'filter-fabrication',
'konstruksi' => 'filter-construction',
'repair' => 'filter-repairs',
'lainnya' => 'filter-design',
];
// 预加载各分类的前 10 条最新作品
$portfoliosByCategory = [];
foreach ($categories as $dbValue => $filterClass) {
$portfoliosByCategory[$dbValue] = Portfolio::where('category', $dbValue)
->latest('created_at') // 明确按 created_at 排序(避免无索引字段歧义)
->take(10)
->get();
}
return view('landing/landing', compact(
'numbers', 'testimonials', 'clients',
'portfoliosByCategory'
));
}✅ Blade 模板正确渲染方式
不再遍历 $portfolios 全集,而是分别渲染每个预处理好的分类集合:
立即学习“前端免费学习笔记(深入)”;
<!-- 分类筛选导航栏(保持不变) -->
<ul class="portfolio-flters" data-aos="fade-up" data-aos-delay="100">
<li data-filter="*" class="filter-active">All</li>
<li data-filter=".filter-fabrication">Fabrikasi</li>
<li data-filter=".filter-construction">Konstruksi</li>
<li data-filter=".filter-repairs">Repair</li>
<li data-filter=".filter-design">Lainnya</li>
</ul>
<!-- 作品网格区域 -->
<div class="portfolio-container">
<!-- Fabrikasi 分类 -->
@foreach($portfoliosByCategory['fabrikasi'] as $portfolio)
<div class="portfolio-item filter-fabrication">
<img src="{{ asset($portfolio->image) }}" class="img-fluid" alt="{{ $portfolio->title }}">
<h4>{{ $portfolio->title }}</h4>
<p>{{ $portfolio->category }}</p>
<a href="{{ asset($portfolio->image) }}"
title="{{ $portfolio->title }}"
data-gallery="portfolio-gallery-fabrikasi"
class="glightbox preview-link">View</a>
</div>
@endforeach
<!-- Konstruksi 分类 -->
@foreach($portfoliosByCategory['konstruksi'] as $portfolio)
<div class="portfolio-item filter-construction">
<img src="{{ asset($portfolio->image) }}" class="img-fluid" alt="{{ $portfolio->title }}">
<h4>{{ $portfolio->title }}</h4>
<p>{{ $portfolio->category }}</p>
<a href="{{ asset($portfolio->image) }}"
title="{{ $portfolio->title }}"
data-gallery="portfolio-gallery-konstruksi"
class="glightbox preview-link">View</a>
</div>
@endforeach
<!-- Repair 分类 -->
@foreach($portfoliosByCategory['repair'] as $portfolio)
<div class="portfolio-item filter-repairs">
<img src="{{ asset($portfolio->image) }}" class="img-fluid" alt="{{ $portfolio->title }}">
<h4>{{ $portfolio->title }}</h4>
<p>{{ $portfolio->category }}</p>
<a href="{{ asset($portfolio->image) }}"
title="{{ $portfolio->title }}"
data-gallery="portfolio-gallery-repair"
class="glightbox preview-link">View</a>
</div>
@endforeach
<!-- Lainnya 分类 -->
@foreach($portfoliosByCategory['lainnya'] as $portfolio)
<div class="portfolio-item filter-design">
<img src="{{ asset($portfolio->image) }}" class="img-fluid" alt="{{ $portfolio->title }}">
<h4>{{ $portfolio->title }}</h4>
<p>{{ $portfolio->category }}</p>
<a href="{{ asset($portfolio->image) }}"
title="{{ $portfolio->title }}"
data-gallery="portfolio-gallery-lainnya"
class="glightbox preview-link">View</a>
</div>
@endforeach
</div>⚠️ 关键注意事项
- 路径安全:确保 $portfolio->image 存储的是相对路径(如 uploads/portfolio/abc.jpg),并在 Blade 中用 asset() 生成完整 URL;若为绝对 URL,请直接输出。
- 排序可靠性:->latest() 默认按 updated_at 排序,建议显式使用 ->latest('created_at') 并确保该字段有数据库索引。
- 空分类容错:可在 @foreach 外加 @if($portfoliosByCategory['fabrikasi']->count()) 判断是否为空,提升健壮性。
- 性能优化:如分类较多或数据量大,可考虑使用 Eloquent 的 when() + 单次查询 + PHP 分组,但当前 4 类 × 10 条完全适用预查询方案。
通过以上重构,每类作品严格展示最新 10 条,且新增作品后自动更新展示内容,彻底规避因循环逻辑错误引发的“图片消失”问题。


















