🦓

[Laravel]Livewireで投稿一覧の表示をソートする

2023/10/23に公開

はじめに

Livewireを使って非同期で投稿をソートできるように実装していきます。

https://livewire.laravel.com/docs/quickstart

環境

PHP 8.x
Laravel 10.x
MySQL 8.x
Livewire 3.x

tl;dr

  1. livewireをインストール
  2. livewireコンポネントを作成する
  3. コンポネートを読み込む
  4. コンポーネントプロパティを定義する
  5. ソートロジックを定義する
  6. ソートするボタンを作成する

livewireをインストールする

composer require livewire/livewire

コンポネントを作成する

投稿を表示およびソートするための新しいLivewireコンポーネントを作成します。

➜   php artisan livewire:make ListingList
 COMPONENT CREATED  🤙

CLASS: app/Livewire/ListingList.php
VIEW:  resources/views/livewire/listing-list.blade.php

app/Livewire/ListingList.phpresources/views/livewire/listing-list.blade.phpを作成されました。

コンポネントを読み込む

作成したコンポネートを投稿一覧に読み込みます。

resources/views/listings/index.blade.php
// 書き方はどちらでも大丈夫
<livewire:listing-list />
@livewire('listing-list')

コンポーネントのプロパティを定義する

app/Livewire/ListingList.php
<?php

namespace App\Livewire;

use App\Models\Listing;
use Livewire\Component;
use Livewire\Attributes\Computed;
use Livewire\WithPagination;

class ListingList extends Component
{
   // ページネーションを有効する
    use WithPagination;

   // コンピューテッド・プロパティ
    #[Computed()]
    public function listings()
    {
        // listings()メソッドに#[Computed]属性が追加されたため、この値はコンポーネント内の他のメソッドやBladeテンプレート内でアクセスできるようになりました。
        return Listing::latest()->with(['user'])->filter(request()->only('search'))->paginate(10);
    }
}

Eloquentモデルのアクセッサのように、コンピュート・プロパティは、値にアクセスし、リクエスト中に将来のアクセスのためにキャッシュすることを可能にします。

コンピューテッド・プロパティは、コンポーネントのパブリック・プロパティと組み合わせると特に便利です。

コンピューテッド・プロパティを作成するには、Livewireコンポーネントの任意のメソッドの上に#[Computed]属性を追加します。属性がメソッドに追加されると、他のプロパティと同様にアクセスできます。

ビューから変数をアクセスする

resources/views/livewire/listing-list.blade.php
@foreach ($this->listings as $listing)
    <x-listing-card :listing="$listing" />
@endforeach

テンプレート内で$thisを使用する必要があります。
通常のプロパティとは異なり、コンピューテッド・プロパティはコンポーネントのテンプレート内で直接使用することはできません。代わりに、$thisオブジェクトからアクセスする必要があります。たとえば、posts()という名前のcomputedプロパティにアクセスするには、テンプレート内で$this->postsを使用しなければなりません。

https://livewire.laravel.com/docs/computed-properties

ソートロジックを定義する

app/Livewire/ListingList.php
<?php

use Livewire\Attributes\Url;

class ListingList extends Component
{

    #[Url()]
    public $sort = 'desc';

    public function sortListing($sort){
        $this->sort = ($sort === 'desc' ? 'desc' : 'asc');
    }
}

#[Url]属性を使用して$sortプロパティを定義します。
#[Url] 属性を使用することで、URLのクエリパラメータをコンポーネント内のプロパティに自動的にバインドできます(?sort=desc または ?sort=asc)。

コンポーネント内の$sortプロパティは、デフォルトで'desc'と初期化されています。
$sortプロパティは、リスト内の項目を降順または昇順でソートするための情報を持たせます。

sortListingメソッドは、引数$sortを受け取り、その値に応じて$sortプロパティを更新します。

URLパラメータを介してソートオプションを受け取り、それに基づいて$sortプロパティを変更し、リストを適切にソートすることができるようになります。

https://livewire.laravel.com/docs/url

ソートするボタンを作成する

resources/views/livewire/listing-list.blade.php
<nav class="-mb-px flex space-x-8">
    <button class="{{ $sort === 'desc' ? 'text-indigo-600' : 'text-gray-400'}}"
      wire:click="sortListing('desc')">新しい順</button>
    <button class="{{ $sort === 'asc' ? 'text-indigo-600' : 'text-gray-400'}}"
      wire:click="sortListing('asc')">古い順</button>
</nav>

https://livewire.laravel.com/docs/wire-click#using-wireclick-on-links

終わりに

これで非同期で投稿一覧の表示をソートすることができましたー
時間順だけではなくタグでソートをしたり、いいね数など条件を追加すればソートすることも可能です。

Discussion