Laravel components の感想

最近Laravel components を触ったので、忘れないうちに色々書いていこうかなぁと思います。

歴史的な話はあまりわからないのですが、2,3年前くらいに Blade に Components 機能が追加されたようです。 一言でいうと Components を作れる機能です(それはそう)。 ちょっと残念なところとして、css名前空間をいい感じに切り分けてくれたりする機能はありません。

そんな話はいいとして、componetsの書き方は色々あるので、今日はこういう感じに使うといいんじゃねーみたいなノウハウを書いていきます。 基本的な機能はdocsを参考にしてください。

まず、コンポーネントに何らかの情報を渡す方法を3つ紹介します。 1つ目はクラスのコンストラクタを設定して渡す方法。

class Alert extends Component
{
    /**
     * Create the component instance.
     */
    public function __construct(
        public string $type,
        public string $message,
    ) {}
 
    /**
     * Get the view / contents that represent the component.
     */
    public function render(): View
    {
        return view('components.alert');
    }
}

// 呼び出し方法
<x-alert type="error" :message="$message"/>

2つ目はComponent Attributes。

<div {{ $attributes }}>
    <!-- Component content -->
</div>

//呼び出し方法
<x-alert type="error" :message="$message" class="mt-4"/>

3つ目がslots。

@props([
    'heading',
    'footer',
])
 
<div {{ $attributes->class(['border']) }}>
    <h1 {{ $heading->attributes->class(['text-lg']) }}>
        {{ $heading }}
    </h1>
 
    {{ $slot }}
 
    <footer {{ $footer->attributes->class(['text-gray-700']) }}>
        {{ $footer }}
    </footer>
</div>

//呼び出し方法
<x-card class="shadow-sm">
    <x-slot:heading class="font-bold">
        Heading
    </x-slot>
 
    Content
 
    <x-slot:footer class="text-sm">
        Footer
    </x-slot>
</x-card>

それぞれが別々の機能というわけではなく密接に関係しています。 あと、割と自由に値を渡す方法を選べる感じなので、初見だとどういう感じで使い分けたらいいんだろうなぁと迷いました。 2,3日やってみた感じだと、slotsの呼び出し例が一番正解に近い感じがするので、ちょろっと解説します。

まず、header, fotter, content で、別々のclass name を取得しています。 例のように、それぞれのHTMLタグに対して、別々のHTMLの属性を付けたいなら、slotsを使うと良さそうです。 これを分けないで書くと、

<x-card contet-class="shadow-sm" header-class="font-bold" footer-class="text-sm" header-message="Heading" footer-message="Footer">
    Content
</x-card>

みたいな感じかなぁ。 もし、footer, content, header に、別のHTMLの属性を付けたくなった場合が面倒で、なぜなら $attributes をfotter, content, header それぞれに分けれないからです。 分けて書くと、どのattributeなのかを指定して書くことができます。

    <h1 {{ $heading->attributes->class(['text-lg']) }}>
        {{ $heading }}
    </h1>

ここまでで、slotsの使い道はほぼ理解できていると思います。

ただ、ここで悩みがあり、下記の場合はどうすればいいでしょう。

<x-alert> sample </x-alert>
or
<x-alert message="sample"/>

どちらでもやりたいことは実現できそうです。 しかし、これら2つの方法で違いがあるとすれば、slotsの場合、恐らくコンポーネント入れ子にすることができます(今この利点を思いついたからやってない)。 なので、上手く使い分けすることができ、コンポーネント入れ子にしたいなら、

<x-alert> sample </x-alert>

単純に文字列などをレンダリングするなら

<x-alert message="sample"/>

でいいのかなぁと思いました。

docsを見ると、まだ使っていない機能が結構ありました。

  • Inline Component Views
  • Dynamic Components
  • props(記事書いているときにはじめて知った&&便利そう)

そこらへんも試してみつつ、気が向いたらまた何か書きまーす。