Paginación
La función de paginación de Laravel te permite consultar un subconjunto de datos y ofrece a tus usuarios la posibilidad de navegar entre las páginas de esos resultados.
Debido a que el paginador de Laravel fue diseñado para aplicaciones estáticas, en una aplicación no Livewire, cada navegación de página desencadena una visita completa del navegador a una nueva URL que contiene la página deseada (?page=2).
Sin embargo, cuando se utiliza la paginación dentro de un componente Livewire, los usuarios pueden navegar entre páginas mientras permanecen en la misma página. Livewire se encargará de todo entre bastidores, incluida la actualización de la cadena de consulta URL con la página actual.
Uso básico
A continuación se muestra el ejemplo más básico de uso de la paginación dentro de un componente ShowPosts para mostrar sólo diez entradas a la vez:
<?php
namespace App\Livewire;
use Livewire\WithPagination;use Livewire\Component;use App\Models\Post;
class ShowPosts extends Component{ use WithPagination;
public function render() { return view('show-posts', [ 'posts' => Post::paginate(10), ]); }}<div> <div> @foreach ($posts as $post) <!-- ... --> @endforeach </div>
{{ $posts->links() }}</div>Como puedes ver, además de limitar el número de entradas mostradas mediante el método Post::paginate(), también usaremos $posts->links() para mostrar los enlaces de navegación de la página.
Para más información sobre paginación en Laravel, consulta la documentación de Laravel sobre paginación.
Desactivar el seguimiento de la cadena de consulta de la URL (URL Query)
Por defecto, el paginador de Livewire rastrea la página actual en la cadena de consulta de la URL del navegador de la siguiente manera: ?page=2.
Si desea seguir utilizando la utilidad de paginación de Livewire, pero desactivar el seguimiento de la cadena de consulta, puede hacerlo utilizando el trait WithoutUrlPagination:
use Livewire\WithoutUrlPagination;use Livewire\WithPagination;use Livewire\Component;
class ShowPosts extends Component{ use WithPagination, WithoutUrlPagination;
// ...}Ahora, la paginación funcionará como se espera, pero la página actual no aparecerá en la cadena de consulta. Esto también significa que la página actual no se mantendrá a través de los cambios de página.
Personalizar el comportamiento de desplazamiento
Por defecto, el paginador de Livewire se desplaza a la parte superior de la página después de cada cambio de página.
Puede desactivar este comportamiento pasando false al parámetro scrollTo del método links() de la siguiente manera:
{{ $posts->links(data: ['scrollTo' => false]) }}Alternativamente, puede proporcionar cualquier selector CSS al parámetro scrollTo, y Livewire encontrará el elemento más cercano que coincida con ese selector y se desplazará hasta él después de cada navegación:
{{ $posts->links(data: ['scrollTo' => '#paginated-posts']) }}Restablecer la página
Cuando se ordenan o filtran resultados, es común querer restablecer el número de página a 1.
Por esta razón, Livewire proporciona el método $this->resetPage(), que permite restablecer el número de página desde cualquier parte del componente.
El siguiente componente demuestra el uso de este método para restablecer la página después de enviar el formulario de búsqueda:
<?php
namespace App\Livewire;
use Livewire\WithPagination;use Livewire\Component;use App\Models\Post;
class SearchPosts extends Component{ use WithPagination;
public $query = '';
public function search() { $this->resetPage(); }
public function render() { return view('show-posts', [ 'posts' => Post::where('title', 'like', '%'.$this->query.'%')->paginate(10), ]); }}<div> <form wire:submit="search"> <input type="text" wire:model="query">
<button type="submit">Buscar Publicaciones</button> </form>
<div> @foreach ($posts as $post) <!-- ... --> @endforeach </div>
{{ $posts->links() }}</div>Ahora bien, si un usuario se encontrara en la página 5 de los resultados y filtrara aún más los resultados pulsando “Buscar Publicaciones”, la página volvería a ser la 1.
Métodos de navegación de página disponibles
Además de $this->resetPage(), Livewire proporciona otros métodos útiles para navegar entre páginas programáticamente desde su componente:
| Método | Descripción |
|---|---|
$this->setPage($page) | Establecer el paginador en un número de página específico |
$this->resetPage() | Restablecer la página 1 |
$this->nextPage() | Ir a la página siguiente |
$this->previousPage() | Ir a la página anterior |
Múltiples paginadores
Dado que tanto Laravel como Livewire utilizan parámetros de cadena de consulta URL para almacenar y rastrear el número de página actual, si una sola página contiene múltiples paginadores, es importante asignarles nombres diferentes.
Para demostrar el problema más claramente, considere el siguiente componente ShowClients:
use Livewire\WithPagination;use Livewire\Component;use App\Models\Client;
class ShowClients extends Component{ use WithPagination;
public function render() { return view('show-clients', [ 'clients' => Client::paginate(10), ]); }}Como puede ver, el componente anterior contiene un conjunto paginado de clients. Si un usuario navegara a la página 2 de este conjunto de resultados, la URL podría tener el siguiente aspecto:
http://application.test/?page=2Supongamos que la página también contiene un componente ShowInvoices que también utiliza la paginación. Para realizar un seguimiento independiente de la página actual de cada paginador, debe especificar un nombre para el segundo paginador de la siguiente manera:
use Livewire\WithPagination;use Livewire\Component;use App\Models\Invoices;
class ShowInvoices extends Component{ use WithPagination;
public function render() { return view('show-invoices', [ 'invoices' => Invoice::paginate(10, pageName: 'invoices-page'), ]); }}Ahora, debido al parámetro pageName que se ha añadido al método paginate, cuando un usuario visite la página 2 de las facturas, la URL contendrá lo siguiente:
https: //application.test/customers?page=2&invoices-page=2;Cuando utilice los métodos de navegación de página de Livewire en un paginador con nombre, debe proporcionar el nombre de la página como parámetro adicional:
$this->setPage(2, pageName: 'invoices-page');
$this->resetPage(pageName: 'invoices-page');
$this->nextPage(pageName: 'invoices-page');
$this->previousPage(pageName: 'invoices-page');Conexión a las actualizaciones de página
Livewire le permite ejecutar código antes y después de que se actualice una página definiendo cualquiera de los siguientes métodos dentro de su componente:
use Livewire\WithPagination;
class ShowPosts extends Component{ use WithPagination;
public function updatingPage($page) { // Se ejecuta antes de que se actualice la página de este componente... }
public function updatedPage($page) { // Se ejecuta después de actualizar la página de este componente... }
public function render() { return view('show-posts', [ 'posts' => Post::paginate(10), ]); }}Hooks del paginador por nombre
Los hooks anteriores sólo se aplican al paginador por defecto. Si utiliza un paginador con nombre, debe definir los métodos utilizando el nombre del paginador.
Por ejemplo, a continuación se muestra un ejemplo de cómo sería un hook para un paginador llamado invoices-page:
public function updatingInvoicesPage($page){ //}Hooks paginadores generales
Si prefieres no hacer referencia al nombre del paginador en el nombre del método hook, puedes utilizar las alternativas más genéricas y simplemente recibir $pageName como segundo argumento del método hook:
public function updatingPaginators($page, $pageName){ // Se ejecuta antes de que se actualice la página para este componente...}
public function updatedPaginators($page, $pageName){ // Se ejecuta después de actualizar la página de este componente...}Usando el tema simple
Puedes usar el método simplePaginate() de Laravel en lugar de paginate() para mayor velocidad y simplicidad.
Al paginar los resultados con este método, solo se mostrarán al usuario los enlaces de navegación siguiente y anterior en lugar de enlaces individuales para cada número de página:
public function render(){ return view('show-posts', [ 'posts' => Post::simplePaginate(10), ]);}Para más información sobre la paginación simple, consulta la documentación “simplePaginator” de Laravel.
Usando la paginación por cursor
Livewire también soporta el uso de la paginación por cursor de Laravel - un método de paginación más rápido útil en grandes conjuntos de datos:
public function render(){ return view('show-posts', [ 'posts' => Post::cursorPaginate(10), ]);}Al utilizar cursorPaginate() en lugar de paginate() o simplePaginate(), la cadena de consulta en la URL de su aplicación almacenará un cursor codificado en lugar de un número de página estándar. Por ejemplo:
https://example.com/posts?cursor=eyJpZCI6MTUsIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0Para más información sobre la paginación por cursor, consulta la documentación de Laravel sobre paginación por cursor.
Usar Bootstrap en lugar de Tailwind
Si utilizas Bootstrap en lugar de Tailwind como framework CSS de tu aplicación, puedes configurar Livewire para que utilice vistas de paginación con estilo Bootstrap en lugar de las vistas predeterminadas de Tailwind.
Para ello, establezca el valor de configuración pagination_theme en el archivo config/livewire.php de su aplicación:
'pagination_theme' => 'bootstrap',Modificación de las vistas de paginación por defecto
Si desea modificar las vistas de paginación de Livewire para adaptarlas al estilo de su aplicación, puede hacerlo publicándolas mediante el siguiente comando:
php artisan livewire:publish --paginationTras ejecutar este comando, se insertarán los cuatro archivos siguientes en el directorio resources/views/vendor/livewire:
| Método | Descripción |
|---|---|
tailwind.blade.php | El tema de paginación estándar de Tailwind |
tailwind-simple.blade.php | El sencillo tema de paginación Tailwind |
bootstrap.blade.php | El tema de paginación estándar de Bootstrap |
bootstrap-simple.blade.php | l sencillo tema de paginación de Bootstrap |
Una vez que los archivos han sido publicados, usted tiene control total sobre ellos. Cuando renderice enlaces de paginación utilizando el método ->links() del resultado paginado dentro de su plantilla, Livewire utilizará estos archivos en lugar de los suyos propios.
Uso de vistas de paginación personalizadas
Si desea omitir por completo las vistas de paginación de Livewire, puede renderizar las suyas propias de dos maneras:
- El método
->links()en su vista Blade - El método
paginationView()opaginationSimpleView()en su componente
Mediante ->links()
El primer enfoque es simplemente pasar el nombre de la vista Blade de paginación personalizada al método ->links() directamente:
{{ $posts->links('custom-pagination-links') }}Al renderizar los enlaces de paginación, Livewire buscará ahora una vista en resources/views/custom-pagination-links.blade.php.
Mediante paginationView() o paginationSimpleView()
El segundo método consiste en declarar un método paginationView o paginationSimpleView dentro de su componente que devuelva el nombre de la vista que desea utilizar:
public function paginationView(){ return 'custom-pagination-links-view';}
public function paginationSimpleView(){ return 'custom-simple-pagination-links-view';}Ejemplo de vista de paginación
Abajo hay un ejemplo sin estilo de una vista de paginación simple de Livewire para tu referencia.
Como puedes ver, puedes usar las ayudas de navegación de Livewire como $this->nextPage() directamente dentro de tu plantilla añadiendo wire:click="nextPage" a los botones:
<div> @if ($paginator->hasPages()) <nav role="navigation" aria-label="Pagination Navigation"> <span> @if ($paginator->onFirstPage()) <span>Anterior</span> @else <button wire:click="previousPage" wire:loading.attr="disabled" rel="prev">Anterior</button> @endif </span>
<span> @if ($paginator->onLastPage()) <span>Siguiente</span> @else <button wire:click="nextPage" wire:loading.attr="disabled" rel="next">Siguiente</button> @endif </span> </nav> @endif</div>