Laravel分页按钮使用自定义模板

在ThinkPHP中分页按钮组的自定义样式模板问题可以通过修改paginator类来解决,但是这个并不是长久之计,因为框架中的东西通常给定了就尽量不去修改,以免在再部署时丢失掉修改的项目,并且现在大多数开发者都会使用composer进行组件管理,修改框架类库无疑为共同协作开发造成极大影响

ThinkPHP目前也有不错的解决方案了,通过extend扩展定义自己的分页按钮组类库来解决,但今天不谈ThinkPHP,而是想谈谈Laravel的解决方案

Laravel的解决方案要简单得多,在编写接口的时候我就注意到当查询语句使用了Paginate()后会在return回来的json数据里加入以下数据

first_page_url	"https://dd.jitui.moe/api/indexinfo?page=1"
from	1
last_page	8
last_page_url	"https://dd.jitui.moe/api/indexinfo?page=8"
next_page_url	"https://dd.jitui.moe/api/indexinfo?page=2"
path	"https://dd.jitui.moe/api/indexinfo"
per_page	5
prev_page_url	null
to	5
total	36

在Larevel的类库中找到\framework\src\Illuminate\Database\Query,打开Builder.php后发现simplePaginate()和Paginate()会在默认情况下使用 Pagination类库\resources\views文件夹下面的模板,这对应着simple和default两个不同的模板配置

而前端模板里面的{{ $datas->links() }}中的links()则对应着Paginator类Paginator.php中的links(),在前端模板的links()中传递参数会让类库中的links()里的render()取得参数并寻找对应位置的模板配置,render()默认参数为$defaultSimpleView,这在之前框架已经默认定义好了,在不传参的情况下也确实会使用该模板进行渲染

public static $defaultSimpleView = 'pagination::simple-bootstrap-4';

在了解清楚Paginator类的links()和render()后,替换分页按钮组样式模板的方法就十分明了了

在前端模板中使用:

{{ $datas->links('common.pagination') }}

$datas是我们要显示的数据,links()的参数则为分页按钮组样式模板的位置,这里pagination.blade.php放置的位置是resources\views\common

下一步开始编写按钮组模板

@if ($paginator->hasPages())
    <div class="btn-group pagination-sm" role="group">
        @if($paginator->currentPage() > 2)
            <a class="btn btn-outline-dark btn-lg" role="button" href="{{ $paginator->url(1) }}">1</a>
        @endif
        @if($paginator->currentPage() > 3)
            @if($paginator->currentPage()-2 >= 10)
                <a class="btn btn-outline-dark btn-lg dol-num"
                   href="{{ $paginator->url($paginator->currentPage()-2) }}" role="button">{{$paginator->currentPage()-2}}</a>
            @else
                <a class="btn btn-outline-dark btn-lg"
                   href="{{ $paginator->url($paginator->currentPage()-2) }}" role="button">{{$paginator->currentPage()-2}}</a>
            @endif
        @endif
        @foreach(range(1, $paginator->lastPage()) as $i)
            @if($i >= $paginator->currentPage() - 1 && $i <= $paginator->currentPage() + 1)
                @if($i >= 10)
                    @if ($i == $paginator->currentPage())
                        <a class="btn btn-dark btn-lg dol-num" href="">{{ $i }}</a>
                    @else
                        <a class="btn btn-outline-dark btn-lg dol-num" href="{{ $paginator->url($i) }}">{{ $i }}</a>
                    @endif
                @else
                    @if ($i == $paginator->currentPage())
                        <a class="btn btn-dark btn-lg" href="">{{ $i }}</a>
                    @else
                        <a class="btn btn-outline-dark btn-lg" href="{{ $paginator->url($i) }}">{{ $i }}</a>
                    @endif
                @endif
            @endif
        @endforeach
        @if($paginator->currentPage() < $paginator->lastPage() - 2)
            @if($paginator->currentPage()+2 >= 10)
                <a class="btn btn-outline-dark btn-lg dol-num"
                   href="{{ $paginator->url($paginator->currentPage()+2) }}" role="button">{{$paginator->currentPage()+2}}</a>
            @else
                <a class="btn btn-outline-dark btn-lg"
                   href="{{ $paginator->url($paginator->currentPage()+2) }}" role="button">{{$paginator->currentPage()+2}}</a>
            @endif
        @endif
        @if($paginator->currentPage() < $paginator->lastPage() - 1)
            @if($i >= 10)
                <a class="btn btn-outline-dark btn-lg dol-num"
                   href="{{ $paginator->url($paginator->lastPage()) }}">{{ $paginator->lastPage() }}</a>
            @else
                <a class="btn btn-outline-dark btn-lg"
                   href="{{ $paginator->url($paginator->lastPage()) }}">{{ $paginator->lastPage() }}</a>
            @endif
        @endif
    </div>
@endif

当然,这里我使用的是bootstrap4的按钮组样式,可根据情况自行修改

由于在适配移动设备页面时会出现页面过多而导致按钮组过长撑出页面,所以在这里我写的时候按钮组仅显示7个,即首末页+当前页+当前页前后两页,这样在移动设备中也不会导致页码过多

如果是前后端分离,那就更简单了,直接使用文章开头的返回数据即可

发表评论

电子邮件地址不会被公开。 必填项已用*标注