【Laravel實戰】15分鐘搞懂Livewire組件分頁功能

【Laravel實戰】15分鐘搞懂Livewire組件分頁功能

Livewire 讓你得以在組件中去為顯示結果進行分頁,這個功能會導用 Laravel 內建的分頁功能,因此這個功能會讓你感覺不到它的存在,但對於使用者體驗卻會有質的提升,因為進行分頁時將不再需要整個頁面重載了

比如你有一個 show-posts 組件,但你希望限制每頁只顯示最多10篇文章,你能夠透過 Livewire 所提供的 WithPagination trait 來進行結果分頁

//app/Http/Livewre/ShowPosts.php

use Livewire\WithPagination;

class ShowPosts extends Component
{
    use WithPagination;

    public function render()
    {
        return view('livewire.show-posts', [
            'posts' => Post::paginate(10),
        ]);
    }
}
//resources/views/livewire/show-posts.blade.php

<div>
    @foreach ($posts as $post)
        ...
    @endforeach

    {{ $posts->links() }}
</div>

現在每一頁的底部將會顯示不同的分頁連結介面,而且顯示結果也會予以分頁

如果分頁視圖有出現超連結但是點下去沒反應,請檢查一下組件視圖的根元素是否超過一個

在過濾資料後重新進行分頁

一種常見的需求是當使用者進行資料過濾操作之後,分頁應該跳回第一頁,分頁結果也跟著重設

例如,假如使用者正位在分頁的第4頁,這時他在搜尋欄輸入關鍵字來進一步縮小查詢範圍,這時候往往使用者會預期分頁應該跳回第1頁

Livewire 的 WithPagination trait 釋出了 resetPage() 來協助你達成這個功能

這個方法能夠搭配 updating/updated 生命週期 hooks 以便於在某些組件資料更新時去重設當前分頁

//app/Http/Livewire/ShowPosts.php

use Livewire\WithPagination;

class ShowPosts extends Component
{
    use WithPagination;

    public $search = '';

    public function updatingSearch()
    {
        $this->resetPage();
    }

    public function render()
    {
        return view('livewire.show-posts', [
            'posts' => Post::where('title', 'like', '%'.$this->search.'%')->paginate(10),
        ]);
    }
}

使用 Bootstrap 分頁主題

就像是 Laravel , Livewire 的預設分頁視圖也是使用 Tailwind 框架來設定樣式。假如你希望在應用裡頭使用 Bootstrap,你能夠使用組件的 $paginationTheme 屬性來在分頁視圖上啟用 Bootstrap 主題

//app/Http/Livewre/ShowPosts.php

class ShowPosts extends Component
{
    use WithPagination;

    protected $paginationTheme = 'bootstrap';

使用自定義的分頁視圖

Livewire 提供了兩種方式來自定義分頁連結視圖,會在呼叫 $results->links() 後進行渲染

方法 A:直接將視圖名稱傳入 links()

//resources/views/livewire/show-posts.blade.php

<div>
    @foreach ($posts as $post)
        ...
    @endforeach

    {{ $posts->links('custom-pagination-links-view') }}
</div>

方法 B:在你的組件去複寫 paginationView()

//app/Http/Livewre/ShowPosts.php

class ShowPosts extends Component
{
    use WithPagination;

    ...

    public function paginationView()
    {
        return 'custom-pagination-links-view';
    }

    ...
}

方法 C:發布 Livewire 的分頁視圖

你能夠透過以下的 Artisan 命令來發布 Livewire 的分頁視圖到 resources/views/vendor/livewire

php artisan livewire:publish --pagination

很遺憾的,Livewire 將會覆寫你定義在服務供應器,使用 Paginator:defaultView() 的自定義視圖

一旦你採用以上的任何一個方法,你應該使用 wire:click 搭配以下方法來跳轉分頁,而不是在你的分頁組件去使用 anchor 標籤

方法 說明
nextPage() 跳至下一頁
previousPage() 跳至上一頁
gotoPage($page) 跳至指定頁

看看下面的例子來了解預設的 Livewire 分頁器是如何運作的

//resources/views/customs/custom-pagination-links-view.blade.php

@if ($paginator->hasPages())
    <nav role="navigation" aria-label="Pagination Navigation" class="flex justify-between">
        {{-- Previous Page Link --}}
        @if ($paginator->onFirstPage())
            <span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
                {!! __('pagination.previous') !!}
            </span>
        @else
            <a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
                {!! __('pagination.previous') !!}
            </a>
        @endif

        {{-- Next Page Link --}}
        @if ($paginator->hasMorePages())
            <a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
                {!! __('pagination.next') !!}
            </a>
        @else
            <span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
                {!! __('pagination.next') !!}
            </span>
        @endif
    </nav>
@endif

分享這篇文章:

關聯文章:

訂閱電子報,索取 Laravel 學習手冊

價值超過 3000 元,包含常用 Laravel 語法與指令!

Laravel 百萬年薪特訓營

從最基礎的 PHP 語法開始,包含所有你該知道的網頁基礎知識,連同 Laravel 從零開始一直到實戰,最後還將告訴你如何找好工作,讓你及早擁有百萬年薪