Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як правильно робити пагінацію в Livewire-компоненті?

Звичайна пагінація Laravel перезавантажує сторінку на кожен перехід. У Livewire-компоненті перехід між сторінками відбувається без перезавантаження, а номер сторінки все одно записується в URL (?page=2).

use Livewire\Attributes\Computed;
use Livewire\WithPagination;

new class extends Component {
    use WithPagination;

    public string $search = '';

    public function updatedSearch(): void
    {
        $this->resetPage();
    }

    #[Computed]
    public function posts()
    {
        return Post::query()
            ->where('title', 'like', "%{$this->search}%")
            ->with('author')
            ->latest()
            ->paginate(20);
    }
};
<input wire:model.live.debounce.300ms="search">

@foreach ($this->posts as $post)
    <article wire:key="{{ $post->id }}">...</article>
@endforeach

{{ $this->posts->links() }}

Ключові моменти:

  • трейт WithPagination обов'язковий - без нього посилання пагінації ведуть на звичайні URL з перезавантаженням;
  • пагінатор - в обчислюваній властивості чи в render(), а не в публічній властивості: пагінатор не серіалізується як стан компонента;
  • resetPage() при зміні фільтра - інакше користувач на 5-й сторінці, змінивши пошук, побачить порожню 5-ту сторінку нових результатів;
  • методи навігації: setPage(3), nextPage(), previousPage().

Кілька пагінаторів на сторінці конфліктують за параметр page - потрібна власна назва:

return Invoice::paginate(10, pageName: 'invoices-page');
$this->resetPage(pageName: 'invoices-page');

Швидкість на великих таблицях:

  • paginate() виконує ще й COUNT(*) по всьому набору - на мільйонах рядків це дорого;
  • simplePaginate() - лише «Попередня / Наступна», без підрахунку;
  • cursorPaginate() - курсор у URL замість номера сторінки, не сповільнюється на глибоких сторінках (немає OFFSET), але не дає перейти на довільну сторінку.

Прокрутка після переходу. Посилання пагінації Livewire після кожного переходу прокручують до початку сторінки. Якщо список - не перший блок на сторінці, краще прокручувати до нього: {{ $this->posts->links(data: ['scrollTo' => '#posts']) }}, або вимкнути прокрутку ('scrollTo' => false).

Без номера сторінки в URL - трейт WithoutUrlPagination поряд з WithPagination (наприклад, для списку в модальному вікні).

Нескінченна стрічка замість сторінок - острівець з wire:island.append і wire:intersect на «маркері» внизу списку.

Докладніше в документації: Пагінація

Схожі питання