Laravel10 + Livewire3 でPaginationを実装していきます。
![](https://macocci7.net/blog/wp-content/uploads/cocoon-resources/blog-card-cache/b19aed21c2592180278960544da4721b.png)
この記事のゴール
- Laravel10 + Livewire3の環境でPaginationを実装
- スタイル適用で見やすくする
- WEBブラウザでユーザー一覧の表示切替をする
前提条件
- Ubuntu上で作業しています
- PHP8.2以降インストール済
- Composer v2以降インストール済
環境構築(Laravel10 + Livewire3)
作業フォルダ内に新規プロジェクト「pagination-livewire」を作成していきます。
composer create-project laravel/laravel:^10 pagination-livewire
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_01-1.png)
プロジェクトフォルダ内に移動してから、
Livewireをインストールしていきます。
cd pagination-livewire/
composer require livewire/livewire:^3
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_02.png)
プロジェクトトップにある「.env」を編集・保存します。
DB_CONNECTION=sqlite
に修正して、それ以外のDB項目を削除します。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_03.png)
「database/seeders/DatabaseSeeder.php」を編集・保存します。
// \App\Models\User::factory(10)->create();
の箇所を修正します。
\App\Models\User::factory(150)->create();
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_04.png)
シードオプション付きでマイグレーション実行します。
php artisan migrate --seed
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_05.png)
ユーザーが150件作成されました。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_06.png)
Livewireコンポーネント作成
次のコマンドでコンポーネントを作成します。
php artisan make:livewire users
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_07.png)
筆者はこのアスキーアートでテンションが上がります。
「app/Livewire/Users.php」
「resources/views/livewire/users.blade.php」
の2ファイルが作成されました。
クラスファイル編集
公式の注意書きとして、WithPaginationトレイトを使えとあります。
You must use the
WithPagination
traitTo take advantage of Livewire’s pagination features, each component containing pagination must use the
Pagination | Laravel LivewireLivewire\WithPagination
trait.
自動翻訳:
WithPagination 特性を使用する必要があります
Livewire のページネーション機能を利用するには、ページネーションを含む各コンポーネントで LivewireWithPagination トレイトを使用する必要があります。
「app/Livewire/Users.php」を開いて編集・保存します。
<?php
namespace App\Livewire;
use Livewire\Component;
use Livewire\WithPagination;
use App\Models\User;
class Users extends Component
{
use WithPagination;
public function render()
{
return view('livewire.users', [
'users' => User::paginate(10),
]);
}
}
ビューファイル編集
「resources/views/livewire/users.blade.php」を編集・保存します。
<div>
<div>
@isset ($users)
<ul>
@foreach ($users as $user)
<li>{{ $user->id }}: {{ $user->name }} <{{ $user->email }}></li>
@endforeach
</ul>
@else
<p>No users.</p>
@endisset
</div>
{{ $users->links() }}
</div>
ルーティング
「routes/web.php」に追記します。
Route::get('/users', \App\Livewire\Users::class);
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_08-1.png)
テンプレートレイアウト作成
次のコマンドを実行します。
php artisan livewire:layout
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_09.png)
「resources/views/components/layouts/app.blade.php」
が作成されました。
WEBサービス起動
次のコマンドでWEBサービスを起動します。
php artisan serve
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_10.png)
ブラウザで確認
WEBブラウザで
http://127.0.0.1:8000/users
にアクセスします。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_11.png)
このような感じで表示されました。
スタイル適用されていないので見づらいですが、
一応機能はしています。
![](http://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_14.png)
スタイルを適用してみる
Tailwind CSSのCDN版を適用してみます。
「resources/views/components/layouts/app.blade.php」に
<script src="https://cdn.tailwindcss.com"></script>
を追記します。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_15.png)
WEBブラウザを再読み込みしてみます。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_16.png)
スタイルは適用されましたが、ページ番号が消えてしまいました。
Paginationテンプレートを修正してページ番号を表示し、スタイルを調整して見やすくしていきます。
まずは、Livewireで使用しているPaginationテンプレートをpublishします。
php artisan livewire:publish --pagination
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_17.png)
「resources/views/vendor/livewire/」フォルダに
4個のテンプレートが展開されました。
![](http://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_19.png)
デフォルトの「tailwind.blade.php」を同じフォルダに
「tailwind-modified.blade.php」としてコピーし、
編集・保存します。
長いのでやったことを列記します。
- 「<<Previous」「Next>>」を削除
- 「Showing …」を削除
- 現在のページを背景青、テキスト白に変更
- マウスホバーで背景黄色に変更
@php
if (! isset($scrollTo)) {
$scrollTo = 'body';
}
$scrollIntoViewJsSnippet = ($scrollTo !== false)
? <<<JS
(\$el.closest('{$scrollTo}') || document.querySelector('{$scrollTo}')).scrollIntoView()
JS
: '';
@endphp
<div>
@if ($paginator->hasPages())
<nav role="navigation" aria-label="Pagination Navigation" class="flex items-center justify-between">
<div class="sm:flex-1 sm:flex sm:items-center sm:justify-between">
<div>
<span class="relative z-0 inline-flex rounded-md shadow-sm">
<span>
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<span aria-disabled="true" aria-label="{{ __('pagination.previous') }}">
<span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5" aria-hidden="true">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
</span>
</span>
@else
<button type="button" wire:click="previousPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" dusk="previousPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}.after" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white hover:bg-yellow-400 border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
</button>
@endif
</span>
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<span aria-disabled="true">
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 cursor-default leading-5 select-none">{{ $element }}</span>
</span>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
<span wire:key="paginator-{{ $paginator->getPageName() }}-page{{ $page }}">
@if ($page == $paginator->currentPage())
<span aria-current="page">
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-white bg-blue-700 border border-gray-300 cursor-default leading-5 select-none">{{ $page }}</span>
</span>
@else
<button type="button" wire:click="gotoPage({{ $page }}, '{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white hover:bg-yellow-400 border border-gray-300 leading-5 hover:text-gray-500 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150" aria-label="{{ __('Go to page :page', ['page' => $page]) }}">
{{ $page }}
</button>
@endif
</span>
@endforeach
@endif
@endforeach
<span>
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<button type="button" wire:click="nextPage('{{ $paginator->getPageName() }}')" x-on:click="{{ $scrollIntoViewJsSnippet }}" dusk="nextPage{{ $paginator->getPageName() == 'page' ? '' : '.' . $paginator->getPageName() }}.after" class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white hover:bg-yellow-400 border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:border-blue-300 focus:shadow-outline-blue active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
</svg>
</button>
@else
<span aria-disabled="true" aria-label="{{ __('pagination.next') }}">
<span class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5" aria-hidden="true">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
</svg>
</span>
</span>
@endif
</span>
</span>
</div>
</div>
</nav>
@endif
</div>
「resources/views/livewire/users.blade.php」
を編集・保存します。
<div>
{{ $users->onEachSide(1)->links('vendor.livewire.tailwind-modified') }}
<div>
@isset ($users)
<ul class="p-6 divide-y divide-slate-200">
@foreach ($users as $user)
<li class="flex px-6 py-2 hover:bg-green-200 rounded-lg">{{ $user->id }}: {{ $user->name }} <{{ $user->email }}></li>
@endforeach
</ul>
@else
<p>No users.</p>
@endisset
</div>
</div>
ページネーションを最上部に移動、
現在のページの両脇1件ずつを指定、
テンプレート「vendor.livewire.teilwind-modified」を指定、
ユーザー一覧もスタイル適用しました。
WEBブラウザを再読み込みして見ます。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_20.png)
スタイル適用がうまくいっていますね。
![](https://macocci7.net/blog/wp-content/uploads/2024/02/laravel_livewire3_pagination_21.png)
ユーザー一覧の方もスタイル適用されています。
今回はここまでです。お疲れさまでした。
続きはこちらです。
コメント