🦓
[Laravel]AlpineJS+Livewireでモーダルコンポーネントを作る
はじめに
Livewire 3.xからAlpineJSをインクルードされるようになったのでAlpineJS+Livewireでモーダルコンポーネントを作っていきます。
環境
PHP 8.x
Laravel 10.x
MySQL 8.x
Livewire 3.x
tl;dr
Livewire 3.xをインストールされたことを前提で進めます。
- モーダルコンポーネントを作成する
- モーダルを定義する
- モーダルを使う
モーダルコンポーネントを作成する
php artisan make:component Modal
INFO Component [app/View/Components/Modal.php] created successfully.
モーダルを定義する
x-data
ディレクティブを使ってモーダルを定義していきます。
x-data
は Alpine.js で使用されるディレクティブの1つで、特定のコンポーネントや要素にデータをバインドするために使用されます。
x-data
により、その要素内でデータの追跡、変更、操作が行えるようになります。
ボタンをクリックしてモーダルを開く
resources/views/components/modal.blade.php
<x-button x-on:click="$dispatch('open-modal', 'モーダル名')">
モーダル
</x-button>
$dispatch
を使ってopen-modal
イベントを発火させます。
open-modal
を定義する
イベントshow
がfalse
の場合モーダルを非表示、true
の場合表示するように定義します。
resources/views/components/modal.blade.php
<div
x-data = "{ show: false }" // モーダルを非表示
x-on:open-modal.window="$event.detail == '{{ $name }}' ? show = true : null" // モーダル名があれば表示する、ない場合非表示
x-on:close="show = false" // closeイベント
x-on:keydown.escape.window="show = false" // escapeキーをクリックしたら非表示
x-show="show" // モーダルの表示
class=""
style="display: {{ $show ? 'block' : 'none' }};"
>
...
</div>
x-show
はDOM要素の表示と非表示を制御するためのディレクティブです。
クローズボタンをクリックしてモーダルを閉じる
$dispatch
を使ってclose
イベントを発火させます。
resources/views/components/modal.blade.php
<x-close-button x-on:click="$dispatch('close')">
// クローズボタン
</x-close-button>
モーダルコンテンツ以外をクリックしてモーダルを閉じる
背景をクリックしてモーダルを閉じるように背景にクリックレスポンスを追加します。
resources/views/components/modal.blade.php
<div
x-show="show"
class=""
x-on:click="show = false"
>
// モーダル背景
<div class="absolute inset-0 bg-gray-400 opacity-75"></div>
</div>
モーダルを使う
@props
ディレクティブを使ってモーダルコンポーネントのプロパティを定義します。
@props
は、Bladeビューでコンポーネントを使用する際に、コンポーネントにデータを渡すための仕組みです。
resources/views/components/modal.blade.php
@props([
'name', // モーダル名
'show' => false // デフォルトでは非表示
])
投稿一覧にある投稿をクリックしたら内容をモーダルに表示されるように実装します。
app/livewire/PostList.php
<?php
namespace App\Http\Livewire;
use LivewireUI\Modal\ModalComponent;
class PostList extends Component
{
public function viewPost(Post $post){
$this->dispatch('open-modal', name: 'view-post');
}
}
resources/views/livewire/post-list.blade.php
@foreach ($this->posts as $post)
...
<x-button wire.click="viewPost({{ $post }})">
投稿を見る
</x-button>
@endforeach
<x-modal name="view-post">
...
<x-close-button>
閉じる
</x-close-button>
</x-modal>
終わりに
簡単ですがAlpineJS+Livewireでのモーダルコンポーネントでした。
Livewire公式のモーダルコンポーネントもあるのでそちらをインストールして使うこともできます!
Discussion