Laravel で開発していると、次のような記述は日常的に目にします。
<x-layouts.app>
<x-alert type="error">
入力内容を確認してください
</x-alert>
</x-layouts.app>
x- が付く記述は特に珍しいものではなく、
Jetstream や Breeze などのスターターキットでも普通に使われています。
ただ、
- Blade コンポーネントをあまり積極的に使ってこなかった
@extendsベースのレイアウトで事足りていた- props や
$slotの動きが曖昧なまま使っている
といった状態だと、何となく使えてはいるけど、
「使えてはいるけど、いまいち理解に自信がない」
という感覚のままになりがちです。
Livewire を使う際にも Blade コンポーネントの考え方は前提として出てくるため、 ここで一度、動作の仕組みを整理しておきます。
1. コンポーネントとは
Blade コンポーネントとは、
再利用可能な UI 部品を、HTML タグのように呼び出せる仕組み
です。
たとえば、ボタンの HTML を毎回書いていると、
- クラス指定がばらつく
- 微妙に見た目が変わる
- 仕様変更時に修正箇所が増える
といった問題が起きやすくなります。
そこで、ボタンをコンポーネントとして切り出しておくことで、
<x-button type="submit" variant="primary">
保存
</x-button>
のように、
- 呼び出し側:何を表示するかを書く
- コンポーネント側:HTML の詳細を持つ
という役割分担が可能になります。
2. コンポーネントの仕組み
Blade は、リクエストを受けるたびに サーバー側で HTML を生成してからブラウザへ返すという仕組みです。
Blade コンポーネントも同様に、
- 呼び出し側で指定された値を受け取り
- コンポーネント内部で HTML を組み立て
- 完成した HTML として出力する
という流れで動作します。
React や Vue のようにブラウザ上でコンポーネントが動作するわけではなく、 Blade コンポーネントはあくまで「HTML 生成用のテンプレート部品」です。
props の受け渡し
呼び出し側で指定した属性は、 コンポーネント側で props として受け取られます。
<x-alert type="error" title="失敗しました" />
PHP 変数などを渡す場合は、先頭に : を付けます。
<x-alert :type="$type" :title="__('失敗しました')" />
コンポーネント側での受け取り
匿名コンポーネントでは、
@props を使って受け取る値を定義します。
@props([
'type' => 'info',
'title' => null,
])
<div class="alert alert-{{ $type }}">
@if($title)
<strong>{{ $title }}</strong>
@endif
{{ $slot }}
</div>
ここで、
$type$title
が props に対応し、
<x-alert type="error">
入力内容を確認してください
</x-alert>
の中身は、
$slot
として扱われます。
attributes の扱い
props として定義されていない属性(class など)は、
$attributes にまとめて格納されます。
<x-button class="w-full">
保存
</x-button>
コンポーネント側では次のように書くことで、
<button {{ $attributes->merge(['class' => 'btn']) }}>
{{ $slot }}
</button>
呼び出し側の class をマージできます。
3. コンポーネントの保存場所
<x-...> は Blade がコンポーネントとして解釈するための構文であり、
通常は以下のディレクトリに対応する Blade ファイルを参照します。
resources/views/components
対応関係の例
| 呼び出し | 保存場所 |
|---|---|
<x-alert /> |
resources/views/components/alert.blade.php |
<x-user.card /> |
resources/views/components/user/card.blade.php |
x-layout の場合
<x-layout />
は、
resources/views/components/layout.blade.php
に対応します。
また、
<x-layouts.app />
の場合は、
resources/views/components/layouts/app.blade.php
を参照します。なお、
@extends('layouts.app')
は、
resources/views/layouts/app.blade.php
を参照する従来のレイアウト機能であり、 Blade コンポーネントとは別の仕組みです。
まとめ
<x-...>は Blade コンポーネント呼び出し構文- 属性は props として渡される
- タグの中身は
$slot - class などは
$attributes - コンポーネントはサーバー側で HTML を生成
- 保存場所は resources/views/components 配下