Laravel 8 中如何避免重复编码实现全站通用导航栏搜索功能
Laravel全局导航搜索功能复用解决方案
方案1:统一专属搜索路由(最推荐,无重复代码)
直接让所有页面的搜索表单提交到同一个独立路由,完全不需要在现有页面的控制器中加逻辑:
- 修改导航栏搜索表单的
action属性,固定指向全局搜索路由,不要提交到当前页路由:
<!-- 导航栏搜索表单代码 --> <form action="{{ route('global.search') }}" method="GET" class="nav-search"> <input type="text" name="search_keyword" placeholder="输入搜索内容" required> <button type="submit">搜索</button> </form>
- 在
routes/web.php中注册全局搜索路由:
Route::get('/global-search', [\App\Http\Controllers\SearchController::class, 'index'])->name('global.search');
- 新建
SearchController,把所有搜索逻辑、结果页渲染逻辑都写在该控制器的index方法中即可,所有页面的搜索请求都会走这一套逻辑。
方案2:公共逻辑封装复用(适合搜索后留在当前页过滤内容的场景)
如果你的需求是搜索后不跳转、仅过滤当前页面的内容,可以把搜索逻辑抽成公共模块复用,不需要每个控制器重复写判断:
- 新建Trait封装搜索逻辑:
// app/Traits/PerformsSearch.php trait PerformsSearch { /** * 给查询构造器应用搜索条件 * @param \Illuminate\Database\Eloquent\Builder $query 原始查询对象 * @param string|null $keyword 搜索关键词 * @param array $searchFields 要匹配搜索的字段列表 * @return \Illuminate\Database\Eloquent\Builder */ public function applySearchFilter($query, $keyword, array $searchFields) { return $query->when($keyword, function ($q) use ($keyword, $searchFields) { $q->where(function ($subQuery) use ($keyword, $searchFields) { foreach ($searchFields as $field) { $subQuery->orWhere($field, 'like', "%{$keyword}%"); } }); }); } }
- 需要支持搜索的控制器引入Trait直接调用即可,仅需1行代码:
// 示例:分类页控制器 use App\Traits\PerformsSearch; use Illuminate\Http\Request; class CategoryController extends Controller { use PerformsSearch; public function viewCategory(Request $request) { $baseQuery = \App\Models\Post::where('category_id', $request->category_id); // 调用公共搜索方法,传入要搜索的字段即可 $posts = $this->applySearchFilter($baseQuery, $request->search_keyword, ['title', 'content', 'excerpt'])->get(); return view('category', compact('posts')); } }
方案3:视图合成器(适合搜索结果在全局组件展示的场景)
如果你的搜索结果需要展示在导航栏、侧边栏这类每个页面都有的公共组件中,可以用Laravel的视图合成器给所有加载了主布局的视图自动注入搜索相关数据,不需要每个控制器手动传参。
内容的提问来源于stack exchange,提问作者Razvan Adrian Prata
相关产品推荐
相关产品推荐

