
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、このブログに記事を書くために普段からいろいろな情報を集めるようにしているのですが、それでもはやり限界があって全ての情報を取得することは難しいものです。
先日もクライアントさんに教えていただいたのですが、どうやら livewire というLaravelのコンポーネント・システムが公開されているとのことでした。(いつも有益な情報ありがとうございます)
早速調べたところ、livewire
のコンセプトは「最近のJavaScriptはちょっとしたことするだけなのに、複雑な作業が必要。もう、そういうのやめよう!」というものでした。
たしかに、最近のJavaScript
開発は、npm
を使って変更をwatch
して、ビルドの完了を待って、やっとできたと思ったらまた変更が必要で・・・再読込が追いつかない・・・(以下繰り返し)
みたいな状況になるので、livewire
のコンセプトにとても賛成です。(私自身もビルドはnpm
のパッケージのみで独自のコードは直接Blade
に書き込む形式をとっています)
そこで!
今回は、そんな気になるlivewire
の使い方を分かりやすくまとめてみることにしました。
ぜひ皆さんのお役に立てると嬉しいです
開発環境: Laravel 5.8
目次 [非表示]
livewireの仕組み
livewire
といってもcomposer
のパッケージのひとつで、Laravel
のテンプレート・エンジンBlade
でコンポーネントを描画します。
そして、コンポーネントの内容をリアルタイムに変更(例えば、テキストの表示/非表示の切り替え)ができるのですが、これはAjax
を通してPHP側からHTMLを取得します。
そして、その通信はlivewire
がやってくれるので独自にコードを書く必要はありません。
やりたいこと
今回は、以下のように誕生日(年・月・日)を入力すると自動的に年齢を計算して表示してくれるコンポーネント「birthday」を作ってみます。
なお、「日」のセレクトボックスは各月に合わせて28日〜31日が自動的に変更されるようにし、さらに「うるう年」の場合は「2月29日」も表示するようにします。
では、実際にlivewire
をインストールしてコードを書いてみましょう!
livewireをインストールする
先ほども言いましたがlivewire
はcomposer
にパッケージが用意されていますので、以下のコマンドだけでインストールが完了します。
composer require calebporzio/livewire
livewireに必要なファイルを作成する
ファイルの作成はlivewire
が用意してくれているartisan
コマンドで作成することができます。
以下のコマンドを実行してください。
php artisan make:livewire birthday
すると、以下2つのファイルが自動的に作成されます。
- /app/Http/Livewire/Birthday.php ・・・ コンポーネントを管理するPHPクラス
- /resources/views/livewire/birthday.blade.php ・・・ コンポーネントのビュー
コンポーネントに必要なコードを追加する
先ほど作成したファイルに必要なコードを追加していきます。
それぞれみていきましょう。
PHPクラス
中身はlivewire
が用意しているComponet
クラスを拡張する形になっています。中身を以下のように変更してください。
/app/Http/Livewire/Birthday.php
<?php
namespace App\Http\Livewire;
use Carbon\Carbon;
use Livewire\Component;
class Birthday extends Component
{
// ここの変数がビュー内で変数として使える
public $year = 0;
public $month = 0;
public $day = 0;
public $age = -1;
public $last_day_of_month = 0;
// 準備が完了したら実行される
public function mount($year = 0, $month = 0, $day = 0) {
$this->year = $year;
$this->month = $month;
$this->day = $day;
$this->onChange();
}
// 入力ボックスに変更があった場合に呼ばれる
public function onChange()
{
$year = intval($this->year);
$month = intval($this->month);
$day = intval($this->day);
// 該当月の日(28〜31日)を計算
if($year > 0 && $month > 0) {
$this->last_day_of_month = Carbon::create($this->year, $this->month)->endOfMonth()->day;
}
// 年齢を計算
if(checkdate($month, $day, $year)) {
$this->age = Carbon::createFromDate($this->year, $this->month, $this->day)->age;
} else {
$this->age = -1;
}
}
public function render()
{
return view('livewire.birthday');
}
}
まず、ここで重要なのが「publicメンバ変数」です。
今回のコードでは5つ変数を宣言していますが、これらは自動的に/resources/views/livewire/birthday.blade.php
の中で、通常の変数として利用することができます。
{{ $year }}
{{ $month }}
{{ $day }}
{{ $age }}
{{ $last_day_of_month }}
続いてmount()
ですが、これはコンポーネントの準備ができた時点で呼ばれるメソッドです。
コンポーネントの呼び出しは以下のようになりますが、このmount()
に引数を用意しているとその次のようにデフォルト値を指定することも可能になります。
@livewire('birthday')
デフォルト値あり↓↓↓
@livewire('birthday', 2000, 12, 31)
また、onChange()
は(年・月・日)が変更されたときに実行されるメソッドですが、この中では以下2つのことを行っています。
- 「日」のセレクトボックスの内容を変更(28日〜31日)
- 年齢を計算
ビュー
では、ビューにもコードを追加していきましょう。
/resources/views/livewire/birthday.blade.php
<div>
<!-- 年 -->
<select name="birth-year" wire:model="year" wire:change="onChange">
<option></option>
@for($i = 1900 ; $i <= date('Y') ; $i++)
<option value="{{ $i }}">{{ $i }}年</option>
@endfor
</select>
<!-- 月 -->
<select name="birth-month" wire:model="month" wire:change="onChange">
<option></option>
@for($i = 1 ; $i <= 12 ; $i++)
<option value="{{ $i }}">{{ $i }}月</option>
@endfor
</select>
<!-- 日 -->
<select name="birth-day" wire:model="day" wire:change="onChange">
<option></option>
@for($i = 1 ; $i <= $last_day_of_month ; $i++)
<option value="{{ $i }}">{{ $i }}日</option>
@endfor
</select>
<!-- 年齢 -->
@if($age > -1)
/ {{ $age }} 才
@endif
</div>
この中では、(年・月・日)のセレクトボックスと年齢を表示しているだけですが、重要なのは「日」のセレクトボックスにある$last_day_of_month
の部分です。なぜなら、この数字が条件によって28日〜31日に変更されることになるからです。
また、年齢は-1
(初期値)の場合は表示をしないようにしています。
コンポーネントを表示させる
では、ここまでで作成したコンポーネントをLaravel
のページに表示させてみます。
とはいっても、livewire
専用のディレクティブが用意されているのでビュー内で以下のようにするだけです。
<html>
<head>
@livewireStyles
</head>
<body>
<div>
@livewire('birthday')
</div>
@livewireScripts
</body>
</html>
【追記:2020.3.21】バージョンアップによる変更があったため修正しました。過去バージョンでは@livewireStyles
、@livewireScripts
の代わりに@livewireAssets
を使ってください。
@livewire('*****')
がコンポーネント本体、そして@livewireStyles
、@livewireScripts
がスタイルシートとJavaScriptを描画する部分になります。
テストしてみる(動画)
では、今回作成したlivewire
コンポーネントを実行してみましょう!(2000年はうるう年なので、2月が29日まであることに注目して見てください)
うまくいきました!
お疲れ様でした
おわりに
ということで、今回ははじめてlivewire
に挑戦してみましたが、使ってみた感想としては、「直感的で使いやすい!」でした。
というのも、livewire
と言ってもテンプレートエンジンはBlade
が使えますし、PHP側も通常よくあるクラスのパターンと同じなので、Laravelを使ってる方でしたらすぐ使えるようになると思います。JavaScriptコードもすでに用意してくれていますしね
ただ、一点だけこれからの開発に期待したい部分があって、それが「バインディングデータをJavaScript側から取得しやすくしてほしい」というものでした。
というのも、livewire
コンポーネント内の値を取得するには、document.getElementById
やdocument.querySelector
を使って取得する必要があるようなのですが、コンポーネントを同じページで複数使う場合は少しややこしくなってしまいます。
そのため、例えば以下のようにref
やid
を指定できるようにして・・・
<!-- 注:このやり方は存在しません -->
@livewire('birthday')
@ref('my-birthday')
@endlivewire
<lw:birthday id="partners-birthday"></lw:birthday>
Vueのように値が直接アクセスできればより便利かなと感じました。
// 注:このやり方は存在しません
livewire.$refs['my-birthday'].year;
といっても、現時点でGitHub
のスターが781
となっていて相当注目を集めているので、きっとこれから進化していくと思います。ということで、私もこれからのlivewire
に注目したいと思います。(時間が出来たらpull request
とかしてみようかな)
ぜひ、皆さんもlivewire
に挑戦してみてくださいね。
ではでは〜!