从数据库分页

  1. // PostsController
  2. public function index()
  3. {
  4. return view('posts.index', ['posts' => DB::table('posts')->paginate(20)]);
  5. }

以上 paginate(20) , 表示每页有 20 条记录, 并且会根据 url 地址栏的 page 参数(如果有的话), 确定当前位于那一页. 每个 Eloquent 模型都有相同的 paginate 方法.

当渲染页面时, collection 将会返回一个 links() 方法, 用来展示翻页按钮(默认使用 Bootstrap 组件库的样式).

// posts/index.blade.php
<table>
@foreach ($posts as $post)
    <tr><td>{{ $post->title }}</td></tr>
@endforeach
</table>

{{ $posts->links() }}

// By default, $posts->links() will output something like this:
<ul class="pagination">
    <li class="page-item disabled"><span>&laquo;</span></li>
    <li class="page-item active"><span>1</span></li>
    <li class="page-item">
        <a class="page-link" href="http://myapp.com/posts?page=2">2</a>
    </li>
    <li class="page-item">
        <a class="page-link" href="http://myapp.com/posts?page=3">3</a>
    </li>
    <li class="page-item">
        <a class="page-link" href="http://myapp.com/posts?page=2" rel="next">
            &raquo;
        </a>
    </li>
</ul>

tips:自定义页码两边的个数

// laravel 5.7 之后
DB::table('posts')->paginate(10)->onEachSide(3);
// Outputs:
// 5 6 7 [8] 9 10 11

自定义分页

有时你没有用 Eloquent 或者 查询构建器, 或者有时你的查询太复杂了(如: 使用groupBy), 你可能发现你要自己实现分页. 幸好 larave 提供了 Illuminate\Pagination\PaginatorIlluminate\Pagination\LengthAwarePaginator 两个类, 可供你使用.

Paginator 只提供 上一页 下一页, 没有为每一页都创建链接; LengthAwarePaginator 需要知道整个结果集合的长度, 然后为每个子页面生成链接. 所以对于结果长度很大的情况下 LengthAwarePaginator 会消耗更多的性能.

PaginatorLengthAwarePaginator 都只需要你手动提取一个子集(你将要渲染到页面的内容的子集), 例子如下:

use Illuminate\Http\Request;
use Illuminate\Pagination\Paginator;

Route::get('people', function (Request $request) {
    $people = [...]; // huge list of people

    $perPage = 15;
    $offsetPages = $request->input('page', 1) - 1;

    // The Paginator will not slice your array for you
    $people = array_slice(
        $people,
        $offsetPages * $perPage,
        $perPage
    );

    return new Paginator(
        $people,
        $perPage
    );
});