8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Laravel Livewire 親子コンポーネント間での値の受け渡し

Posted at

内容

LaravelのLivewireを使用している環境での、親子間での値の受け渡し方法を書いています。
基本的には値を渡したいコンポーネントの関数を呼び出して値を伝達するのが良いと思います。

注意: Livewireのバージョンに注意しましょう

バージョンの違うドキュメントを見て時間を溶かしました。
バージョン 2.x なのか、3.xなのか初めに確認してください。
私はバージョン 3.xです。

親から子へ値を渡す

wire:propディレクティブによる値渡し

子コンポーネントを描画する際に、:タグ名="値"と記述することで、値を渡すことができます。
この方法の場合、リアルタイムな値の反映はできません。

livewire Blade
<livewire:child-component :number="$num" />

タグと値を受け取ったコンポーネントは、以下の条件に一致するコンポーネントクラスのプロパティへ代入を行います。

  • タグ名とプロパティ名が一致する
  • publicなプロパティ
PHP コンポーネントクラス
class ChildComponent extends Component
{
    public $number;
    ...
}

親から子のイベントを発火させての値渡し

親コンポーネントにて、子コンポーネントへの値伝達を開始するトリガーを実装します。
この方法の場合、リアルタイムな値の反映が可能です。

以下の二つがあるかと思います。

  1. wire:clickを使って、クリックなどのアクションをトリガーにする
  2. 親コンポーネントクラスのプロパティが変更されたことを検知するupdatedプロパティ名のメソッドを実装。wire:model.liveにて、値の変更を毎回検知してトリガーにする

私は2の方法で実装しました。

まず、親bladeに、wire:model.liveを記述し、値変更をすぐに検知するようにします。

親 livewire Blade
<input type="text" wire:model.live="parentText">

親コンポーネントクラスで、以下を記述します。

  1. bladeと同名のプロパティ
  2. updatedプロパティ名のメソッド
親 PHP コンポーネントクラス
class ParentComponent extends Component
{
    // bladeと同名のプロパティを記述
    public $parentText = "";

    // updatedプロパティ名のルールに従ってメソッドを記述
    // $parentTextの値が変更されるたびに呼ばれる
    public function updatedParentText()
    {
        // dispatch
        // 第一引数に記述されたイベントが発行されます
        // イベントをリッスンしている子コンポーネントが発火します
        // 第二引数の値が、発火した関数に渡されます
        $this->dispatch('updateText', $this->parentText);
    }

    public function render()
    {
        return view('livewire.parent-component');
    }
}

子コンポーネントクラスで、以下を記述します。

  1. リッスンするイベントprotected $listeners
  2. イベント発行を検知して起動するメソッド
子 PHP コンポーネントクラス
class ChildComponent extends Component
{
    public $childText;

    // リッスンするイベント名
    protected $listeners = ['updateText'];

    // イベント検知時に起動するメソッド
    public function updateText($text)
    {
        // 親コンポーネントクラスから受け取った値を
        // 自身のプロパティへ代入
        $this->childText = $text;
    }

    public function render()
    {
        return view('livewire.child-component');
    }
}

子bladeに、wire:model.liveを記述し、値変更をすぐに反映するようにします。

子 livewire Blade
<input type="text" wire:model.live="childText">

子から親へ値を渡す

基本的には上記の内容(親から子のイベントを発火させての値渡し)の逆をやります。
バージョン 2.xだとそれぞれやり方が違うようですが、バージョン 3.xだと基本的に同じやり方でできるようです。
参考用にコードだけ記述します。

親 livewire Blade
<input type="text" wire:model.live="parentText">
親 PHP コンポーネントクラス
class ParentComponent extends Component
{
    public $parentText = "";

    protected $listeners = ['updateText'];

    public function updateText($text)
    {
        $this->parentText = $text;
    }
    
    public function render()
    {
        return view('livewire.parent-component');
    }
}
子 PHP コンポーネントクラス
class ChildComponent extends Component
{
    public $childText;

    public function updatedChildText()
    {
        $this->dispatch('updateText', $this->childText);
    }

    public function render()
    {
        return view('livewire.child-component');
    }
}
子 livewire Blade
<input type="text" wire:model.live="childText">

Livewireコンポーネント描画時の注意点

以下のような、子コンポーネントを複数回描画する記述を行った場合、何かの再描画のタイミングでコンポーネントが消えてしまうことがあります。

@for ($i = 0; $i < 5; $i++)
    <livewire:child-component />
@endfor

その場合、以下のようにwire:keyを記述して、そのページにてユニークなkeyを設定してあげると解消することがあります。
これはLivewireが識別のために使用するだけなので、この記述を追加したからと言ってコンポーネントクラスに何か書いたりする必要はありません。

@for ($i = 0; $i < 5; $i++)
    <livewire:child-component :wire:key="$i" />
@endfor

参考URL

公式ドキュメント

非常に参考になりますが、バージョン 2.xである点に注意してください。
Laravel で爆速ラクチン🔥に動的な機能を開発や!Livewire2.x 解説🔥

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?