Livewire で Fomantic-UI の評価(Rating)を使うには?wire:ignore編
Fomantic-UI の評価(Rating)のように、wire:model が使えないコントーラー(text、radio、checkbox、select、textarea以外)を使うには、どうしたらいいのでしょうか?
今回、「評価(Rating)」を使って確認してみようと思います。
ポイントは
①wire:ignore を使うところ
②onRate(ユーザーが評価を選択した後)のタイミングで 「@this.set(‘rating’,value,[defer]) 」または「@this.rating = value」でプロパティを設定するところ
③アクションメソッドで変更した内容を反映させる為に、アクションメソッドからイベントを発行して 評価コンポーネントの値を更新するところです。
手順
Laravel と Livewire をインストールして、Fomantic-UI の評価(Rating)を使う手順。
- プロジェクト名(rating)を決めて以下のコマンドを実行します。
curl -s https://laravel.build/rating | bash
インストール時にプロジェクト名のディレクトリが作成されます。
- インストールの最後に sudo でパスワードの入力を求められます。
↓下のメッセージが表示されてインストールは終わります。
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
Get started with: cd rating && ./vendor/bin/sail up
- sail のエイリアスを定義します。
echo "alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'" >> ~/.bashrc
source ~/.bashrc
Laravel のインストールはここまで。
- 「sail up」でコンテナを起動します。
cd rating && sail up -d
- ララベルのトップディレクトリで、Livewireパッケージ をインストールします。
sail composer require livewire/livewire
- 次のコマンドを実行して、ratingコンポーネント を生成します。
sail artisan make:livewire rating
$ sail artisan make:livewire rating
COMPONENT CREATED ?
CLASS: app/Http/Livewire/Rating.php
VIEW: resources/views/livewire/rating.blade.php
次の 2つ のファイルが生成されます。
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Rating extends Component
{
public function render()
{
return view('livewire.rating');
}
}
<div>
{{-- The Master doesn't talk, he acts. --}}
</div>
※因みに、renderメソッド を定義しなくても livewire.rating は呼び出されます。
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Rating extends Component
{
}
- 生成された ratingコンポーネント のクラスとビューを次のように置き換えます。
app/Http/Livewire/Rating.php
<?php
namespace App\Http\Livewire;
class Rating extends \Livewire\Component
{
public $rating = 5;
public $max_rating = 10;
public $icon = 'star';
public function dehydrate() {
\Log::debug($this->rating);
}
public function dec() {
--$this->rating;
$this->emit('set-rating',$this->rating);
}
public function inc() {
++$this->rating;
$this->emit('set-rating',$this->rating);
}
}
resources/views/livewire/rating.blade.php には↓下の2つのやり方があります。
① @this.set() で設定する方法
<div wire:ignore>
<div class="ui rating {{ $this->id }}" data-icon="{{ $icon }}" data-rating="{{ $rating }}" data-max-rating="{{ $max_rating }}"></div>
<input type="button" wire:click="dec" value="-">
<input type="button" wire:click="inc" value="+">
<script>
// ratingを表示する。評価変更時にプロパティに設定する。
$('.{{ $this->id }}').rating({onRate:value => @this.set('rating',value,false)})
document.addEventListener('livewire:load',() => {
// アクションメソッドで送信された値を反映する。
Livewire.on('set-rating',rating => $('.{{ $this->id }}').rating('set rating',rating))
})
</script>
</div>
ポイントは「wire:ignore」と「@this.set()」と「Livewire.on(‘set-rating’,…)」です。↓下のプロパティに設定する方法もありますが、第3パラメーターで defer が設定できるので set が良いと思います。Livewire.on ではアクションメソッドで送信された値を設定しています。
② @this.プロパティ に設定する方法
<div wire:ignore>
<div class="ui rating {{ $this->id }}" data-icon="{{ $icon }}" data-rating="{{ $rating }}" data-max-rating="{{ $max_rating }}"></div>
<input type="button" wire:click="dec" value="-">
<input type="button" wire:click="inc" value="+">
<script>
// ratingを表示する。評価変更時にプロパティに設定する。
$('.{{ $this->id }}').rating({onRate:value => @this.rating = value})
document.addEventListener('livewire:load',() => {
// set-ratingイベントで rating に値を設定する。
Livewire.on('set-rating',rating => $('.{{ $this->id }}').rating('set rating',rating))
})
</script>
</div>
ポイントは「wire:ignore」と「@this.プロパティ=value」と「Livewire.on(‘set-rating’,…)」です。
- resources/views/index.blade.php ファイル を作成します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.1/dist/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.0/dist/semantic.min.css">
<script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.9.0/dist/semantic.min.js"></script>
<livewire:styles />
</head>
<body>
<div class="ui basic segment">
<livewire:rating />
</div>
<livewire:scripts />
</body>
</html>
- routes/web.php に Livewireコンポーネント のルートを追加します
Route::get('/', fn() => view('index'));
- ブラウザで確認します。
tail で onRate(ユーザーが評価を選択した後)のタイミングで通信していることを確認しましょう。
tail -f storage/logs/laravel.log
以上