📅  最后修改于: 2023-12-03 15:27:43.802000             🧑  作者: Mango
在 Laravel 中,我们可以使用 paginate()
方法来实现分页查询。当我们在 Blade 模板中使用这个方法生成的分页链接时,可能会发现链接的参数不太符合我们的需求(比如需要删除一些默认的参数)。在这个教程中,我们会介绍如何自定义 Laravel 的分页链接。
在开始之前,我们需要先创建一个 Laravel 项目。我们可以使用以下命令来创建一个新的 Laravel 项目:
laravel new custom-pagination
然后,我们需要创建一个包含数据的模型,用于演示分页功能。我们可以使用以下命令来创建一个新的模型:
php artisan make:model Book -m
这个命令会同时生成一个迁移文件,我们可以在迁移文件中创建一些测试数据。以下是一个示例迁移文件,用于创建 books
表和一些测试数据:
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
class CreateBooksTable extends Migration
{
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->string('author');
$table->timestamps();
});
$data = [
['title' => 'Book 1', 'author' => 'Author 1'],
['title' => 'Book 2', 'author' => 'Author 2'],
['title' => 'Book 3', 'author' => 'Author 3'],
['title' => 'Book 4', 'author' => 'Author 4'],
['title' => 'Book 5', 'author' => 'Author 5'],
['title' => 'Book 6', 'author' => 'Author 6'],
['title' => 'Book 7', 'author' => 'Author 7'],
['title' => 'Book 8', 'author' => 'Author 8'],
['title' => 'Book 9', 'author' => 'Author 9'],
['title' => 'Book 10', 'author' => 'Author 10'],
['title' => 'Book 11', 'author' => 'Author 11'],
['title' => 'Book 12', 'author' => 'Author 12'],
['title' => 'Book 13', 'author' => 'Author 13'],
['title' => 'Book 14', 'author' => 'Author 14'],
['title' => 'Book 15', 'author' => 'Author 15'],
['title' => 'Book 16', 'author' => 'Author 16'],
['title' => 'Book 17', 'author' => 'Author 17'],
['title' => 'Book 18', 'author' => 'Author 18'],
['title' => 'Book 19', 'author' => 'Author 19'],
['title' => 'Book 20', 'author' => 'Author 20'],
];
DB::table('books')->insert($data);
}
public function down()
{
Schema::dropIfExists('books');
}
}
然后,我们需要运行迁移文件来创建表和测试数据:
php artisan migrate
我们可以在 Controller 中使用 paginate()
方法来获取数据并生成分页链接。以下是一个示例 Controller,用于获取数据并在模板中渲染数据和分页链接:
namespace App\Http\Controllers;
use App\Models\Book;
use Illuminate\Http\Request;
class BookController extends Controller
{
public function index(Request $request)
{
$books = Book::paginate(5);
return view('books.index', compact('books'));
}
}
在 Blade 模板中,我们可以使用 links()
方法来渲染分页链接。以下是一个示例模板,用于渲染数据和分页链接:
@foreach ($books as $book)
<div>{{ $book->title }}</div>
<div>{{ $book->author }}</div>
@endforeach
<div>{{ $books->links() }}</div>
默认情况下,Laravel 会在分页链接中包含一些参数,比如 page
和 per_page
。我们可以使用 simplePaginate()
方法来生成不包含这些参数的分页链接,但是这个方法不会包含必要的参数,比如排序和筛选参数。
为了自定义 Laravel 的分页链接,我们需要继承 Illuminate\Pagination\LengthAwarePaginator
类,并重写 url()
方法。以下是一个示例类,用于自定义分页链接:
namespace App\Utils;
use Illuminate\Pagination\LengthAwarePaginator;
class CustomPaginator extends LengthAwarePaginator
{
public function url($page)
{
$url = $this->path . '?page=' . $page;
if (!empty($this->query)) {
$url .= '&' . http_build_query($this->query);
}
return $url;
}
}
在上面的示例中,我们重写了 url()
方法,将返回一个自定义的链接。我们在链接中包含了当前页数和查询参数,但是删除了默认的参数。
在 Controller 中,我们需要使用自定义的类来创建一个分页实例。以下是一个示例 Controller,用于使用自定义分页链接:
namespace App\Http\Controllers;
use App\Models\Book;
use App\Utils\CustomPaginator;
use Illuminate\Http\Request;
class BookController extends Controller
{
public function index(Request $request)
{
$perPage = 5;
$currentPage = $request->input('page', 1);
$sortBy = $request->input('sort_by', 'id');
$sortOrder = $request->input('sort_order', 'desc');
$query = Book::query();
$total = $query->count();
$books = $query->orderBy($sortBy, $sortOrder)
->skip(($currentPage - 1) * $perPage)
->take($perPage)
->get();
$paginator = new CustomPaginator($books, $total, $perPage, $currentPage, [
'path' => $request->url(),
'query' => $request->query(),
]);
return view('books.index', compact('books', 'paginator'));
}
}
在上面的示例中,我们首先获取当前页数和排序参数,然后使用 $query->count()
方法将查询到的总数保存到 $total
变量中。然后我们使用 $query->orderBy()
方法和 $query->skip()
、$query->take()
方法来获取当前页面的数据。
接着,我们使用自定义的 CustomPaginator
类来创建一个分页实例。我们向构造函数传递数据集合、总数、每页记录数、当前页数和一些配置参数。其中,path
参数表示当前链接,query
参数表示查询参数。
最后,我们将数据集合和分页实例传递给模板引擎,让模板引擎渲染数据和分页链接。以下是一个示例模板,用于渲染数据和分页链接:
<table>
<thead>
<tr>
<th><a href="{{ request()->fullUrlWithQuery(['sort_by' => 'id', 'sort_order' => $sortOrder === 'asc' ? 'desc' : 'asc']) }}">ID</a></th>
<th><a href="{{ request()->fullUrlWithQuery(['sort_by' => 'title', 'sort_order' => $sortOrder === 'asc' ? 'desc' : 'asc']) }}">Title</a></th>
<th><a href="{{ request()->fullUrlWithQuery(['sort_by' => 'author', 'sort_order' => $sortOrder === 'asc' ? 'desc' : 'asc']) }}">Author</a></th>
</tr>
</thead>
<tbody>
@foreach ($books as $book)
<tr>
<td>{{ $book->id }}</td>
<td>{{ $book->title }}</td>
<td>{{ $book->author }}</td>
</tr>
@endforeach
</tbody>
</table>
<div>{{ $paginator->links() }}</div>
在上面的示例中,我们使用了 request()->fullUrlWithQuery()
方法来生成包含排序参数的链接。这个方法会生成一个包含当前链接、查询参数和新排序参数的链接。我们还可以使用 request()->except()
方法来删除某些参数,让链接更加简洁。
在本教程中,我们介绍了如何自定义 Laravel 的分页链接。我们首先使用 paginate()
方法和 links()
方法来生成默认的分页链接。然后,我们介绍了如何继承 Illuminate\Pagination\LengthAwarePaginator
类,并重写 url()
方法来生成自定义的分页链接。最后,我们给出了一个完整的示例,用于演示如何使用自定义分页链接。