Symfony Advent Calendar 2021の記事です。
今回はSymfony UXの新機能、Live Componentについて書きます。
Symfony UXとは
なるべくサーバサイドのことに注力できるように、フロントエンドのUXに関するJavaScriptとサーバサイドをうまいこと繋ぎ込んでくれるライブラリ群です。
composerでサーバサイド側のプログラムとnpmパッケージをダウンロードして利用します。
2021年12月現在、以下が用意されています。
name | 内容 |
---|---|
UX Chart.js | Chart.jsがいい感じにつかえるやつ |
UX Cropper.js | Cropper.jsがいい感じにつかえるやつ |
UX Dropzone | ドラッグ&ドロップでファイルアップロードできるようにしてくれるやつ |
UX LazyImage | 画像遅延読み込みをいい感じにしてくれるやつ |
UX Swup | Swupがいい感じにつかえるやつ |
UX Turbo | Hotwire Turboがいい感じにつかえるやつ |
Twig Component | 【実験段階】 再利用可能なTwigコンポーネントがつくれるやつ |
Live Component | 【実験段階】 Ajaxで再描画できるTwigコンポーネントがつくれるやつ |
Live Componentを使ってみる。。前に
Live Componentは、Livewire、Phoenix LiveViewにインスパイアされて作成されたようです。上記で書いた通り、Twig Componentの一種です。まずはTwig Componentについて知る必要があります。
Twig Componentについて
Twig Componentは、コンポーネントクラスとTwigテンプレートのセットで、他のテンプレート上から呼び出すことができます。イメージ的にはEmbed Controllerに似ています。Live Componentもですが、実験段階なライブラリになります。
Twig Componentはいたってシンプルに作ることができます。まずはコンポーネントクラス。
namespace App\Components;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
#[AsTwigComponent('hello')]
class HelloComponent
{
public string $name = '';
public function getGreet(): string
{
return sprintf('こんにちは、%sさん', $this->name);
}
}
アトリビュートで、#[AsTwigComponent('hello')]
をつけることで、hello
という名前のコンポーネントとして利用することができます。
name
を使ってgetGreet()
で挨拶を返します。今回は使っていませんが、**当然オートワイヤリング可能です。**続いてコンポーネントで使うテンプレート。
<div class="greet">
{{ this.greet }}
</div>
コンポーネントクラスのGetterメソッドにはthis.***
という形でアクセスできます。ここではthis.greet
でgetGreet()
にアクセスしています。
最後に、コンポーネントを使う側のテンプレートです。
<div>
<h3>あいさつ</h3>
{{ component('hello', {name: 'ほげほげ'}) }}
</div>
{{ component('コンポーネント名
, 引数) }}`でコンポーネントを呼び出すことができます。引数を設定するとパブリックなプロパティに値を代入してくれます。
上記の結果は、
<div>
<h3>あいさつ</h3>
<div class="greet">
こんにちは。ほげほげさん
</div>
</div>
となります。べんりー。
Live Componentを使ってみる。
さて、本題のLive Componentです。Live Componentでは、すこし記述がかわります。まずはクラス。
namespace App\Components;
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
+ use Symfony\UX\LiveComponent\DefaultActionTrait;
- #[AsTwigComponent('hello')]
+ #[AsLiveComponent('hello')]
class HelloComponent
{
+ use DefaultActionTrait;
+
+ #[LiveProp(writable: true)]
public string $name = '';
public function getGreet(): string
{
return sprintf('こんにちは、%sさん', $this->name);
}
}
アトリビュートが#[AsTwigComponent('hello')]
から#[AsLiveComponent('hello')]
に変更しました。Live Componentへはこれだけで変更されます。
続いてuse DefaultActionTrait;
の追加ですが、再描画行う際にクラス内の__invoke()
を実行するようになっているので、何もしない__invoke()
メソッドを追加します。なお、Live Componentは実質Controllerとのこと。
最後にプロパティの$nameに#[LiveProp(writable: true)]
を追加します。LiveProp
は該当のプロパティをステートフルプロパティに変更します。オプションのwritable: true
をつけることで、上書き可能なプロパティになります。
続いてテンプレート。
- <div class="greet">
+ <div class="greet" {{ init_live_component(this) }}>
+ <input type="text" name="name" value="{{ this.name }}" data-action="live#update">
{{ this.greet }}
</div>
divタグに{{ init_live_component(this) }}
が追加されました。これはライブコンポーネントの初期化が行われます。Symfony UXはStimulusを使用しており、Stimulusの初期化の記述をこれで追加します。
また、名前が変えれるように入力フォームを用意し、data-action="live#update"
を追加しています。テキストボックスにdata-actionを追加すると、入力内容が変わるごとにlive#update
が実行され、Ajax経由でHelloComponent::__invoke()
の実行結果を取得して、再描画を行います。
呼び出す側は修正の必要がありません。
では実行してみましょう。
このような感じで、入力したテキストがすぐに反映されています。
今回のサンプルは単純なものでしたが、DBのデータを扱ったり認可・認証をからめたコンポーネントも作れるようです。
例えば、
こんなのとか。
実験段階なので、まだまだ改修が入りそうですが、ページ再読み込みストレスをかなり軽減してくれる機能となっていて、Symfony UXの中でも今後がとても楽しみな機能です。ぜひ一度お試しください。