内容
LaravelのLivewireを使用している環境での、親子間での値の受け渡し方法を書いています。
基本的には値を渡したいコンポーネントの関数を呼び出して値を伝達するのが良いと思います。
注意: Livewireのバージョンに注意しましょう
バージョンの違うドキュメントを見て時間を溶かしました。
バージョン 2.x なのか、3.xなのか初めに確認してください。
私はバージョン 3.xです。
親から子へ値を渡す
wire:propディレクティブによる値渡し
子コンポーネントを描画する際に、:タグ名="値"
と記述することで、値を渡すことができます。
この方法の場合、リアルタイムな値の反映はできません。
<livewire:child-component :number="$num" />
タグと値を受け取ったコンポーネントは、以下の条件に一致するコンポーネントクラスのプロパティへ代入を行います。
- タグ名とプロパティ名が一致する
- publicなプロパティ
class ChildComponent extends Component
{
public $number;
...
}
親から子のイベントを発火させての値渡し
親コンポーネントにて、子コンポーネントへの値伝達を開始するトリガーを実装します。
この方法の場合、リアルタイムな値の反映が可能です。
以下の二つがあるかと思います。
-
wire:click
を使って、クリックなどのアクションをトリガーにする - 親コンポーネントクラスのプロパティが変更されたことを検知する
updatedプロパティ名
のメソッドを実装。wire:model.live
にて、値の変更を毎回検知してトリガーにする
私は2の方法で実装しました。
まず、親bladeに、wire:model.liveを記述し、値変更をすぐに検知するようにします。
<input type="text" wire:model.live="parentText">
親コンポーネントクラスで、以下を記述します。
- bladeと同名のプロパティ
- updatedプロパティ名のメソッド
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');
}
}
子コンポーネントクラスで、以下を記述します。
- リッスンするイベント
protected $listeners
- イベント発行を検知して起動するメソッド
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を記述し、値変更をすぐに反映するようにします。
<input type="text" wire:model.live="childText">
子から親へ値を渡す
基本的には上記の内容(親から子のイベントを発火させての値渡し)の逆をやります。
バージョン 2.xだとそれぞれやり方が違うようですが、バージョン 3.xだと基本的に同じやり方でできるようです。
参考用にコードだけ記述します。
<input type="text" wire:model.live="parentText">
class ParentComponent extends Component
{
public $parentText = "";
protected $listeners = ['updateText'];
public function updateText($text)
{
$this->parentText = $text;
}
public function render()
{
return view('livewire.parent-component');
}
}
class ChildComponent extends Component
{
public $childText;
public function updatedChildText()
{
$this->dispatch('updateText', $this->childText);
}
public function render()
{
return view('livewire.child-component');
}
}
<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 解説🔥