Laravel9 Blade结合Bootstrap5实现筛选无刷新加载结果方案咨询
Laravel 9 无刷新筛选功能实现方案
你选的「局部视图+jQuery动态加载」方案完全适配当前Blade+Bootstrap5的技术栈,实现简单、维护成本低,不需要引入额外的重型前端框架,具体实现步骤如下:
1. 拆分局部视图
首先把右侧结果展示区的代码单独抽离为局部视图,方便后续AJAX请求时只返回结果片段,不用渲染整页。
新建文件 resources/views/productcategories/partials/_results.blade.php,内容如下:
@foreach ($items as $item) {{$item->name}}<br> {{$item->description}}<br> <a href="/product/{{$item->id}}">查看商品</a><br><br> @endforeach
2. 修改主视图文件
修改原分类页视图(即控制器返回的productcategories/show.blade.php,你提到的Search.blade.php可对应调整),给表单和结果容器加标识,引入局部视图:
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-lg-12"> <h3>分类:{{$category->name}}</h3> </div> {{-- 左侧筛选区 --}} <div class="col-4"> 筛选条件<br><br> <form id="filterForm" data-category-slug="{{$category->slug}}"> 品牌<br> {{-- 给所有筛选项加name属性,方便传参 --}} <select name="brand[]" multiple class="form-control mb-2"> {{-- 循环渲染品牌选项即可 --}} </select> 型号<br> <input type="text" name="model" class="form-control mb-2"> <button type="submit" class="btn btn-primary">确认筛选</button> </form> </div> {{-- 右侧结果区,加固定ID供JS定位 --}} <div class="col-8" id="resultContainer"> @include('productcategories.partials._results', compact('items')) </div> </div> </div> @endsection
3. 调整控制器逻辑
修改控制器的index方法,增加筛选条件处理,同时兼容AJAX请求:AJAX请求时只返回渲染好的局部视图片段,普通访问时返回完整页面。
/** * @param $category_name * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function index($category_name) { // 优化原分类查询,不存在直接返回404 $category = ProductCategory::where('slug', $category_name)->firstOrFail(); // 构建商品基础查询 $itemsQuery = Product::where('category_id', $category->id); // 处理品牌筛选 if (request()->filled('brand')) { $itemsQuery->whereIn('brand', request()->input('brand')); } // 处理型号筛选 if (request()->filled('model')) { $itemsQuery->where('model', 'like', '%' . request()->input('model') . '%'); } // 重量等其他筛选项按相同逻辑扩展即可 if (request()->filled('min_weight')) { $itemsQuery->where('weight', '>=', request()->input('min_weight')); } if (request()->filled('max_weight')) { $itemsQuery->where('weight', '<=', request()->input('max_weight')); } $items = $itemsQuery->take(10)->get(); // AJAX请求直接返回局部视图渲染结果 if (request()->ajax()) { return view('productcategories.partials._results', compact('items'))->render(); } // 普通请求返回完整页面 return view('productcategories/show', compact('category', 'items')); }
4. 增加前端交互逻辑
引入jQuery的前提下,在页面脚本块里加以下代码,拦截表单提交事件,动态加载结果:
$(function () { // 拦截筛选表单提交 $('#filterForm').on('submit', function (e) { // 阻止默认的整页刷新提交 e.preventDefault(); const form = $(this); const resultContainer = $('#resultContainer'); const requestUrl = `/category/${form.data('category-slug')}`; // 加加载态优化体验 resultContainer.html('<div class="text-center py-5">结果加载中...</div>'); // 发请求拿筛选后的结果,替换容器内容 $.get(requestUrl, form.serialize(), function (res) { resultContainer.html(res); }).fail(function () { resultContainer.html('<div class="alert alert-danger">结果加载失败,请重试</div>'); }); }) // 如果需要选完筛选项自动触发筛选、不用点提交按钮,放开下面的注释即可 // $('#filterForm select, #filterForm input').on('change input', function () { // $('#filterForm').trigger('submit'); // }) })
注意事项
- 原有路由不需要修改,只要确保是GET类型的路由
Route::get('/category/{category_name}', [你的控制器类::class, 'index'])即可 - 所有筛选项必须配置
name属性,否则表单序列化时无法传递筛选参数 - 后期修改商品展示样式只需要调整
_results.blade.php局部视图,不需要修改JS拼接逻辑,维护成本远低于前端拼接JSON数据的方案 - 如果项目没有引入jQuery,用原生
fetchAPI实现逻辑完全一致,只是DOM操作写法稍有区别
内容的提问来源于stack exchange,提问作者radgezito
相关产品推荐
相关产品推荐

