我们在之前基于模型+缓存对文章增删改查进行优化一节中提到过,如果文章数量较多,可以对文章列表进行分页,本节我们将以该教程为基础对PostController
的index
方法进行改造,作为Laravel中分页的实例进行讲解。
Laravel中实现分页非常简单,因为Laravel底层为我们提供分页所需的一应组件,从分页逻辑实现到分页视图渲染,我们完全不需要编写任何业务逻辑代码,甚至连视图模板也不用操心,因为Laravel为我们封装了所有实现代码,我们只需要进行几个简单的调用,即可实现强大的分页功能。
Laravel还为分页提供了多种实现方式,既可以基于查询构建器实现分页,也可以基于Eloquent模型进行分页,最终生成的分页视图还兼容Bootstrap CSS样式。讲到这里,估计很多人已经跃跃欲试了,想要迫不及待的看看Laravel到底是如何实现分页的,下面让我们一一道来:
我们可以在查询构建器上简单调用simplePaginate
方法,从而实现类似WordPress默认分页的样式(上一页、下一页这种简单的分页链接):
class PostController extends Controller { /** * 显示文章列表. * * @return Response */ public function index() { //使用查询构建器进行简单分页,每页显示3条记录 $posts = DB::table('posts')->simplePaginate(3); return view('post.index',['posts'=>$posts]); } ... }
就是这么简单,不需要传入页码,不需要传入总数,只是简单调用simplePaginate
方法并传入每页显示数目,如果你想指定查询的字段,页码参数,完整的simplePaginate
定义如下:
simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page')
其中$perPage
表示每页显示数目,$columns
表示查询字段,$pageName
表示页码名称,页码名称默认为page
。
要查看页面显示效果,还需要定义相应的视图文件。
接下来我们创建文章列表页视图文件resources/views/post/index.blade.php
:
<div class="container"> <ul> @foreach ($posts as $post) <li>{{ $post->title }}</li> @endforeach </ul> </div> {!! $posts->render() !!}
保存新建的文件之后,去浏览器访问http://laravel.app:8000/post
,页面显示如下:
点击下一页链接“»”,页面跳转到http://laravel.app:8000/post/?page=2
并显示如下内容:
当然,我们通常见到的分页样式更多是这样的:
那么,这又如何实现呢?
别担心,Laravel已经为我们准备好了相应的实现方法。
要实现上述带页码的分页样式,只需调用查询构建器上的paginate
方法即可:
$posts = DB::table('posts')->paginate(3);
再次访问http://laravel.app:8000/post
,页面显示如下:
显然,分页已经带上页码了,当然,这里我们没有引入Bootstrap,所以样式丑了点。不过学院君会在下月推出的博客项目中让大家彻底告别这种样式,所以暂时忍一忍啦。
同理,我们也可以传递更多参数到paginate
方法,paginate
完整参数定义如下:
paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null)
其中$perPage
代表每页显示数目,$columns
代表查询字段,$pageName
代表页码名称,$page
代表第几页。
除了查询构建器之外,Laravel还支持在Eloquent模型上进行分页,当然我们在之前Eloquent相关教程中已经提到过,其实Eloquent模型本质上也是个查询构建器,所以在Eloquent模型中实现分页实际上调用的还是查询构建器上的那些方法。
因此,如果要实现简单分页,我们可以像这样操作:
$posts = Post::simplePaginate(3);
要实现带页码的分页,调用代码如下:
$posts = Post::paginate(3);
当然,我们可以在Eloquent模型添加更多查询条件:
$posts = Post::where('views','>',0)->paginate(3);
通过查看simplePaginate
和paginate
两个函数的底层实现,可以发现这两个函数分别返回Illuminate\Pagination\Paginator
和Illuminate\Pagination\LengthAwarePaginator
,因此,如果我们想要实现自定义分页功能,需要传入自定义参数到这两个类中。当然,很多时候这两个类已经可以满足我们绝大部分需求,更多的改动可能还是在分页样式上,比如我们想要修改链接的显示、以及在分页链接中加上“首页”、“最后一页”这样的链接等。Laravel自带的分页链接样式由Illuminate\Pagination\BootstrapThreePresenter
的render
方法生成,要想自定义分页样式,需要在这些类和方法上做文章。
未完待续。。。