Open7

livewire3 directives

ハヤシダハヤシダ

wire:click

htmlのクリックトリガー。
htmlの要素にwire:click="download"を書くだけで、componentのdownload関数と自動で紐づけて呼び出してくれる。

component
class ShowInvoice extends Component
{ 
    public function download()
    {
        //ダウンロード処理を書く
    }
}
blade
<button type="button" wire:click="download"> 
    Download !
</button>

wire:click.prevent

preventあり:クリック時にgoogleClick関数の実行と同時に、googleの遷移が走ってしまう。
preventなし:googleClick関数の実行後に、googleの遷移が走るよう遷移処理を制御してくれる。

<a href="https://www.google.co.jp/" wire:click.prevent="googleClick">
    Google!
</a>
ハヤシダハヤシダ

wire:submit formの送信処理

Saveボタンを押すと、<form wire:submit="save"> 経由でComponentのsave関数が呼び出されます。

component
class CreatePost extends Component
{
    public $title = '';
    public $content = '';
 
    public function save()
    {
        Post::create([
            'title' => $this->title,
            'content' => $this->content,
        ]);
 
        $this->redirect('/posts');
    }
}
blade
<form wire:submit="save"> 
    <input type="text" wire:model="title">
    <textarea wire:model="content"></textarea>

    <button type="submit">Save</button>
</form>
ハヤシダハヤシダ

wire:model

公式:https://livewire.laravel.com/docs/wire-model

Componentとbladeのhtml要素を紐づける。
例えば、bladeでwire:model="title"とすると、componentの$titleと紐づきます。

component
class CreatePost extends Component
{
    public $title = '';
    public $content = '';
    public function save()
    {
        $post = Post::create([
            'title' => $this->title
            'content' => $this->content
        ]);
    }
}
blade
<form wire:submit="save">
    <input type="text" wire:model="title"> 
    <textarea wire:model="content"></textarea> 
 
    <button type="submit">Save</button>
</form>

更新頻度の制御

wire:model.xxxxxのようにして使用する。

修飾子 送信頻度 備考
.live 入力するたび リクエストが増大。パフォーマンスが低下する恐れあり
.debounce.250ms 入力停止して250msたったら 数値は変更可能。入力が完了した後にのみ更新に使う
.throttle.250ms 入力のたびに250ms経ったら 数値は変更可能。そこそこ更新内容を残したい時に使う
.change フォーカスが外れる、または値の変更時 Enterキーも含まれる
.blur フォーカスが外れたとき -

そのほかの修飾子

修飾子 説明 備考
.number 入力値をint型でサーバーにキャスト -
.boolean 入力値をbool型でサーバーにキャスト -
.fill ページ読み込み時に、value属性の値で初期化 -
ハヤシダハヤシダ

modelの続き

テキスト入力

自動で紐づくので、value="{{ $title }}"は不要

blade
<input type="text" wire:model="title">

テキストエリア入力

{{ $content }}は不要。

blade
<textarea type="text" wire:model="content"></textarea>

チェックボックス

単一のチェックボックス

blade
<input type="checkbox" wire:model="receiveUpdates">

複数のチェックボックス

component
public $updateTypes = [];
blade
<input type="checkbox" value="email" wire:model="updateTypes">
<input type="checkbox" value="sms" wire:model="updateTypes">

ラジオボタン

blade
<input type="radio" value="yes" wire:model="receiveUpdates">
<input type="radio" value="no" wire:model="receiveUpdates">

ドロップダウン(セレクトボックス)

blade
<select wire:model="animal">
    <option disabled value="">選択してください</option>
    <option value="cat">ねこ</option>
    <option value="dog">いぬ</option>
</select>

ドロップダウンが連動しているとき

県のwire:model名と、市のwire:key名を合わせる。

blade
<!-- 県のメニュー -->
<select wire:model.live="selectedPrefecture">
    @foreach (Prefectures::all() as $prefecture)
        <option value="{{ $prefecture->id }}">{{ $prefecture->label }}</option>
    @endforeach
</select>
 
<!-- 市区町村のメニュー -->
<select wire:model.live="selectedCity" wire:key="{{ $selectedPrefecture }}"> 
    @foreach (City::whereStateId($selectedState->id)->get() as $city)
        <option value="{{ $city->id }}">{{ $city->label }}</option>
    @endforeach
</select>

複数選択ドロップダウン

multiple属性を使用する

blade
<select wire:model="states" multiple>
    <option value="AL">Alabama</option>
    <option value="AK">Alaska</option>
</select>
ハヤシダハヤシダ

wire:loading

ロード中の表示

Saveボタンを押すと、サーバーからレスポンスが返るまで「Saving post...」が表示される

blade
<form wire:submit="save">
    <button type="submit">Save</button>
 
    <div wire:loading> 
        Saving post...
    </div>
</form>

ロード中の要素を削除

ロード中は非表示になります

blade
<div wire:loading.remove>非表示になる文字</div>

クラスの切り替え

ロード中はopacity-50classを付与

blade
<button wire:loading.class="opacity-50">Save</button>

ロード中はclassを削除

blade
<button class="bg-blue-500" wire:loading.class.remove="bg-blue-500">
    Save
</button>

属性の切り替え

デフォルトではフォームが送信されると、「submitボタンの無効化」と「入力要素にreadonlyを付与」を自動的に行ってくれるが、自身で属性を付与することもできる。
下記はsubmitではないため、上記の自動化がなされない。.attrでRemoveボタンを押下後にdisabledを付与している。

blade
<button
    type="button"
    wire:click="remove"
    wire:loading.attr="disabled"
>
    Remove
</button>
ハヤシダハヤシダ

wire:target

targetを使用すれば、特定のトリガーの時だけ削除の時だけloadingを表示させることもできる。
下記では削除ボタンの時だけ「投稿を削除中」が表示される。

blade
<form wire:submit="save">
    <button type="submit">Save</button>
    <button type="button" wire:click="remove">削除</button>
 
    <div wire:loading wire:target="remove">  
       投稿を削除中
    </div>
</form>

targetに複数のボタンを対応させたければ、targetにコンマで区切って渡すこともできる。

blade
<button type="submit">Save</button>
<button type="button" wire:click="remove">Remove</button>
 
<div wire:loading wire:target="save, remove">  
    Updating post...
</div>

テーブルなどで複数のボタンとloadingがある時は、model名に一意のパラメータを渡すと良い。

blade
<button wire:click="remove({{ $post->id }})">Remove</button>
 
<div wire:loading wire:target="remove({{ $post->id }})">  
    Removing post...
</div>

一部のアクションの時だけloadingを表示したくなければ、exceptを使用する。

blade
// downloadのボタンの時はloadingが実行されない
<div wire:loading wire:target.except="download">...</div>
ハヤシダハヤシダ

wire:loadingのCSS対応

次の場合は、loadingが発動するとstyleにdisplay:flexが付与される。

blade
<div wire:loading.flex>...</div>

使用できるcssは以下のとおり。

blade
<div wire:loading.inline-flex>...</div>
<div wire:loading.inline>...</div>
<div wire:loading.block>...</div>
<div wire:loading.table>...</div>
<div wire:loading.flex>...</div>
<div wire:loading.grid>...</div>

loadingインジケーターの遅延

高速にloadingが発動してしまうと、チラついて邪魔になってしまう。
delay(遅延)を使用することで、delay中にレスポンスを受け取った場合はloadingが表示されなくなる。

blade
<div wire:loading.delay.shortest>...</div> <!-- 50ms -->
<div wire:loading.delay.shorter>...</div>  <!-- 100ms -->
<div wire:loading.delay.short>...</div>    <!-- 150ms -->
<div wire:loading.delay>...</div>          <!-- 200ms -->
<div wire:loading.delay.long>...</div>     <!-- 300ms -->
<div wire:loading.delay.longer>...</div>   <!-- 500ms -->
<div wire:loading.delay.longest>...</div>  <!-- 1000ms -->

cssと遅延を同時に使用する

このように2つ同時には実行されない。

blade
<div wire:loading:block.delay>

ネストすることで実行できる?

blade
<div wire:loading:block>
    <div wire:loading.delay></div>
</div>