Laravel 8应用自定义分页项遇问题:求排查与修复方案
Laravel 8 博客分页问题修复
背景说明
我基于Laravel 8开发博客应用,在ArticlesController控制器中实现了带搜索功能的文章分页展示:
namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\User; use App\Models\ArticleCategory; use App\Models\Article; use App\Models\Comment; class ArticlesController extends FrontendController { // 每页文章数量 protected $per_page = 12; public function index(Request $request) { // 搜索关键词 $qry = $request->input('search'); $articlesQuery = Article::where('title', 'like', '%' . $qry . '%') ->orWhere('short_description', 'like', '%' . $qry . '%') ->orWhere('content', 'like', '%' . $qry . '%'); // 搜索结果计数 if ($qry) { $article_count = $articlesQuery->count(); } $articles = $articlesQuery->orderBy('id', 'desc')->paginate($this->per_page); $featured_articles = Article::where('featured', 1)->orderBy('id', 'desc')->get(); return view('themes/' . $this->theme_directory . '/templates/index', array_merge($this->data, [ 'search_query' => $qry, 'articles' => $articles, 'featured_articles' => $featured_articles, 'article_count' => $article_count ?? null ]) ); } }
期望实现的纯HTML分页结构如下:
<nav class="pgn"> <ul> <li> <a class="pgn__prev" href="#0">Prev</a> </li> <li><a class="pgn__num" href="#0">1</a></li> <li><span class="pgn__num current">2</span></li> <li><a class="pgn__num" href="#0">3</a></li> <li><span class="pgn__num dots">…</span></li> <li><a class="pgn__num" href="#0">4</a></li> <li> <a class="pgn__next" href="#0">Next</a> </li> </ul> </nav>
但当前使用的Blade代码仅「Prev」和「Next」按钮可正常工作,中间页码链接失效:
<nav class="pgn"> <ul> <li> <a class="pgn__prev" href="{{ $articles->withQueryString()->previousPageUrl() }}">Prev</a> </li> {!! $articles->withQueryString()->links() !!} <li> <a class="pgn__next" href="{{ $articles->withQueryString()->nextPageUrl() }}">Next</a> </li> </ul> </nav>
1. 问题成因
- Laravel默认的
links()方法会生成完整的分页导航HTML结构(包含自身的<nav>、<ul>、<li>标签),直接将其嵌套在已有的<ul>内部会导致HTML结构嵌套错误,浏览器无法正确解析中间页码的DOM结构,进而导致链接无法正常触发。 - 同时默认分页的类名与需求的
pgn__num、current等不匹配,即使结构正常也无法应用目标样式,但核心故障源于HTML结构冲突。
2. 最简修复方案
通过自定义Laravel分页视图,生成符合需求的结构和类名,步骤如下:
步骤1:导出默认分页视图到项目
在终端执行命令,将Laravel内置的分页视图导出到项目目录:
php artisan vendor:publish --tag=laravel-pagination
执行后,分页视图文件会被保存到resources/views/vendor/pagination目录下。
步骤2:修改分页视图结构
打开导出的视图文件(如bootstrap-4.blade.php,Laravel 8默认使用此模板),替换内容为以下代码,保留分页逻辑的同时适配目标HTML结构:
<nav class="pgn"> <ul> {{-- 上一页按钮 --}} @if ($paginator->onFirstPage()) <li><span class="pgn__prev">Prev</span></li> @else <li><a class="pgn__prev" href="{{ $paginator->withQueryString()->previousPageUrl() }}">Prev</a></li> @endif {{-- 页码链接组 --}} @foreach ($elements as $element) {{-- 省略号处理 --}} @if (is_string($element)) <li><span class="pgn__num dots">{{ $element }}</span></li> @endif {{-- 页码按钮处理 --}} @if (is_array($element)) @foreach ($element as $page => $url) @if ($page == $paginator->currentPage()) <li><span class="pgn__num current">{{ $page }}</span></li> @else <li><a class="pgn__num" href="{{ $paginator->withQueryString()->url($page) }}">{{ $page }}</a></li> @endif @endforeach @endif @endforeach {{-- 下一页按钮 --}} @if ($paginator->hasMorePages()) <li><a class="pgn__next" href="{{ $paginator->withQueryString()->nextPageUrl() }}">Next</a></li> @else <li><span class="pgn__next">Next</span></li> @endif </ul> </nav>
步骤3:在模板中调用分页方法
修改Blade模板,直接调用分页方法即可,无需手动编写Prev/Next按钮:
{!! $articles->withQueryString()->links() !!}
此方式会生成完全符合需求的分页结构,所有链接正常工作,同时保留搜索参数。
内容的提问来源于stack exchange,提问作者Razvan Zamfir
相关产品推荐
相关产品推荐

