深く掘り下げたスクリーンキャストがある、Livewireに驚いてください。観る(英語版)
イントロダクション
Livewireコンポーネントはコンポーネントクラスのパブリックプロパティとして、データを保存および追跡します。
class HelloWorld extends Component
{
public $message = 'Hello World!';
...
Livewireのパブリックプロパティは、自動的にビューで利用可能になります。ビューに明示的に渡す必要はありません。(必要に応じ、渡すこともできます。)
class HelloWorld extends Component
{
public $message = 'Hello World!';
}
<div>
<h1>{{ $message }}</h1>
<!-- "Hello World!"が出力される -->
</div>
重要な注意点
Livewireの旅へ出る前に、パブリックプロパティに関して注意すべき2つの重要事項を次に示します。
- パブリックプロパティに保存したデータは、フロントエンドのJavaScriptで表示可能になります。そのため、機密性の高いデータは保存しないでください。
- プロパティは、JavaScriptに適したデータ型(
string
、int
、array
、boolean
)、もしくは以降のPHPタイプのいずれかのみです。Stringable
、Collection
、DateTime
、Model
、EloquentCollection
Note:
protected
とprivate
プロパティは、Livewireの更新で維持されません。一般に、状態を保存するためにこれらを使用するのは避けるべきでしょう。
プロパティの初期化
コンポーネントのmount
メソッドを使用し、プロパティを初期化できます。
class HelloWorld extends Component
{
public $message;
public function mount()
{
$this->message = 'Hello World!';
}
}
Livewireは多くのプロパティを設定する必要があり、視覚的なノイズを除去したい場合に使える、$this->fill()
メソッドも提供しています。
public function mount()
{
$this->fill(['message' => 'Hello World!']);
}
さらに、パブリックプロパティ値をプログラムで初期状態にリセットできるよう、Livewireは$this->reset()
を提供しています。これは、アクションの実行後に入力フィールドをクリーンアップする場合に便利です。
public $search = '';
public $isActive = true;
public function resetFilters()
{
$this->reset('search');
// searchプロパティのみリセット
$this->reset(['search', 'isActive']);
// searchとisActiveプロパティの両方をリセット
}
データ結合
VueやAngularなどのフロントエンドフレームワークを使用したことがある場合は、すでにこの概念はおなじみでしょう。しかし、もしこうした概念に慣れていなければ、Livewireはコンポーネントの特定のプロパティへ、一部のHTML要素の現在値を「結合」(または「同期」)できると理解してください。
class HelloWorld extends Component
{
public $message;
}
<div>
<input wire:model="message" type="text">
<h1>{{ $message }}</h1>
</div>
ユーザーがテキストフィールドに何かを入力すると、$message
プロパティの値が自動的に更新されます。
内部的にLivewireは要素の「入力」イベントをリッスンし、トリガーが起きると、AJAXリクエストを送信し、コンポーネントを新しいデータで再レンダーリングします。
Tip!!
input
イベントをディスパッチする任意の要素にwire:model
を追加できます。カスタム要素、またはサードパーティのJavaScriptライブラリでも可能です。
wire:model
を使用する一般的な要素は以下のとおりです。
要素タグ |
---|
<input type="text"> |
<input type="radio"> |
<input type="checkbox"> |
<select> |
<textarea> |
ネストしたデータの結合
Livewireはドット記法による配列内のネストしたデータへの結合をサポートしています。
<input type="text" wire:model="parent.message">
入力のデバウンス
デフォルトでLivewireは、テキスト入力に150msのデバウンスを適用します。これにより、ユーザーがテキストフィールドに入力するときに送信されるネットワークリクエストが多くなりすぎるのを防いでいます。
このデフォルトをオーバーライド(またはテキスト以外の入力へ追加)したい場合のために、Livewireは"debounce"修飾子を提供します。入力に0.5秒のデバウンスを適用する場合は、以下のように修飾子を指定します。
<input type="text" wire:model.debounce.500ms="name">
レイジーな更新
デフォルトでは、Livewireはすべてのinput
イベント(ある場合によってはchange
)の後に、サーバーにリクエストを送信します。これは通常、高速に更新しない<select>
要素のようなものには問題ありませんが、ユーザーのタイピングに応じて更新されるテキストフィールドには不必要なことがよく起きます。
そのような場合は、lazy
ディレクティブ修飾子を使用して、ネイティブのchange
イベントをリッスンします。
<input type="text" wire:model.lazy="message">
これで、$message
プロパティは、ユーザーがこの入力フィールドから離れるクリックをしたときにのみ更新されます。
遅延更新
リアルタイムにデータの更新を行う必要がない場合、Livewireには次のネットワークリクエストでデータの更新をバッチ処理する.defer
修飾子があります。
たとえば、次のコンポーネントがあるとします。
<input type="text" wire:model.defer="query">
<button wire:click="search">Search</button>
ユーザーが<input>
フィールドへタイピングしても、ネットワークリクエストは送信されません。ユーザーがページ上の他のフィールドをクリックし、入力フィールドから離れてもリクエストは送信されません。
ユーザーが"Search"を押すと、Livewireは新しい"query"状態と検索を実行するための"search"アクションの両方を含むネットワーク要求を1つ送信します。
これにより、不要な場合のネットワーク使用量を大幅に削減できます。
モデルプロパティへの直接バインド
EloquentモデルがLivewireコンポーネントのパブリックプロパティとして保存されている場合は、そのプロパティに直接結合できます。コンポーネントの一例をご覧ください。
use App\Post;
class PostForm extends Component
{
public Post $post;
protected $rules = [
'post.title' => 'required|string|min:6',
'post.content' => 'required|string|max:500',
];
public function save()
{
$this->validate();
$this->post->save();
}
}
<form wire:submit.prevent="save">
<input type="text" wire:model="post.title">
<textarea wire:model="post.content"></textarea>
<button type="submit">Save</button>
</form>
上記のコンポーネントでは、"title"および"content"モデル属性を直接結合していることに注意してください。Livewireは、現在の非永続データを使用して、リクエスト間のモデルのハイドレーションとデハイドレーションを処理します。
Note: これを機能させるには、結合したいモデル属性に対するバリデーションエントリを
$rules
プロパティに用意します。これをしない場合はエラーが投げられます。
さらに、Eloquentコレクション内のモデルにも結合できます。
use App\Post;
class PostForm extends Component
{
public $posts;
protected $rules = [
'posts.*.title' => 'required|string|min:6',
'posts.*.content' => 'required|string|max:500',
];
public function mount()
{
$this->posts = auth()->user()->posts;
}
public function save()
{
$this->validate();
foreach ($this->posts as $post) {
$post->save();
}
}
}
<form wire:submit.prevent="save">
@foreach ($posts as $index => $post)
<div wire:key="post-field-{{ $post->id }}">
<input type="text" wire:model="posts.{{ $index }}.title">
<textarea wire:model="posts.{{ $index }}.content"></textarea>
</div>
@endforeach
<button type="submit">Save</button>
</form>
算出プロパティ
Livewireは、動的プロパティにアクセスするためのAPIを提供します。これは、データベースやキャッシュなどの別の永続ストアからプロパティを取得する場合にとくに役立ちます。
class ShowPost extends Component
{
// 算出プロパティ
public function getPostProperty()
{
return Post::find($this->postId);
}
これで、コンポーネントのクラスまたはブレードビューから$this->post
にアクセスできます。
class ShowPost extends Component
{
public $postId;
public function getPostProperty()
{
return Post::find($this->postId);
}
public function deletePost()
{
$this->post->delete();
}
}
<div>
<h1>{{ $this->post->title }}</h1>
...
<button wire:click="deletePost">Delete Post</button>
</div>
Tip!! 算出プロパティは、個々のLivewireリクエストライフサイクルごとにキャッシュされます。つまり、コンポーネントのBladeビューで
$this->post
を5回呼び出しても、毎回個別のデータベースクエリが作成されるわけではありません。