Laravel 7以降のBladeコンポーネントはどう便利になったか


Laravel 7で、Bladeコンポーネントが拡張された。最初知ったときは、わざわざHTML風の
文法になっているのがいまいちだと感じたが、よく調べてみるとしっかりとした意図のあ
る仕様で、便利そうだった。

どう変わったのか、またどう便利になったのか、具体的に紹介する。

参考:
リリースノート 7.x Laravel の"Bladeコンポーネントタグと向上"以下。

変更点

ほかにも細かいものはあるが、主に以下の3つが重要だろう。

1. <x-.../>とHTMLタグのように呼び出せるようになった

HTMLタグのように書くことができる。この呼び出し方では、自動的にresources/views/components以下のビューがコンポーネントとして呼び出される。

渡すデータも、HTML属性のように表記できる。PHPの変数を渡したい場合は、先頭に:を付加する。

{{-- Laravel 6まで --}}
@component('form.input.number', ['name' => 'foo', 'min' => 0, 'max' => $max])
@endocmponent
{{-- Laravel 7から --}}
<x-input.number name="foo" min="0" :max="$max" />

あるいは、

<x-input.number name="foo" min="0" :max="$max">
</x-input.number>

2. HTML属性を簡単に渡せる"属性バッグ"が追加された

渡した変数を{{ $attributes }}だけで表示できる。下記の例のようにオプションとして使う場合にはより有用だ。

resources/views/form/input/number.blade.php
{{-- Laravel 6まで --}}
<input type="number" name="{{ $name }}" @isset ($min) min="{{ $min }}" @endisset @isset ($max) max="{{ $max }}"@endisset value="{{ old($name) }}">
resources/views/components/input/number.blade.php
{{-- Laravel 7から --}}
<input type="number" {{ $attributes }} value="{{ old($name) }}">

3. Bladeビューとしてではなく、PHPのクラスとしてコンポーネントを表現するコンポーネントクラスを作れるようになった

これにより、コンポーネントが受け取るデータを明示することができるようになったのが非常に強力だ。

ほかにも、コンポーネントクラスに実装したメソッドをビュー側で変数として使用することができる。

app/View/Components/Input/Number.php
<?php

namespace App\View\Components\Input;

use Illuminate\View\Component;

class Number extends Component
{
    /** @var string */
    public $name;

    /**
     * インスタンスを生成する
     *
     * @param  string $name
     * @return void
     */
    public function __construct(string $name)
    {
        $this->name = $name;
    }

    /**
     * ビューを取得する
     *
     * @return \Illuminate\Contracts\View\View
     */
    public function render()
    {
        return view('components.input.number'); # あるいは、文字列をそのまま返すこともできる
    }
}

まとめ: どう便利になったのか

上記のサンプルコードを見れば大体わかると思うが、もう少し説明すると、

  1. 呼び出し側はHTML風の文法のおかげで、短くわかりやすく書けるようになった。
  2. コンポーネント側は属性バッグのおかげで、オプションの属性を短くわかりやすく書けるようになった。
  3. コンポーネントクラスのおかげで、コンポーネントが受け取るデータを型を含めて明示することができるようになった。
  4. また、関連するロジックをコンポーネントクラスに入れることができるようになった。

といったところだろうか。

ただ個人的には、コンポーネントクラスはそこまで必要ないと思っている。追加の属性値に関しては属性バッグでシンプルに書けるようになり、また紹介しなかったが@props()を使うことでも受け取るデータの名前に関しては明示できるようになっているためだ。

どちらにしてもメリットが強力で、デメリットも特に見当たらないため、Laravel 7以上が使える環境であれば、Bladeコンポーネントの新機能を使わない理由はなさそうだ。

参考:
Bladeテンプレート 7.x Laravel の"コンポーネント"以下。

この記事のライセンス


この文書はCC BY(クリエイティブ・コモンズ表示4.0国際ライセンス)で公開する。

この文書内のサンプルコードはMITライセンスで公開する。