LaravelのBlade Componentsを使いこなすための基礎
LaravelのBlade Templatesの使い方はわかっているけどLaravel 7から登場したBlade Componentsを使った経験がない人っていませんか?Blade Componentsのリリースから時間は経過しましたが本文書ではBlade Componentsについて基礎から説明を行っています。
最新バージョンのLaravel 11ではフロントエンド側で利用できるJetStream, Breezeのパッケージの各所でBlade Componentsが利用されています。Laravel 11を使いこなすためにはBlade Componentsの理解が必要となります。
Blade ComponentsにはClassファイルを利用するClassベースComponentsとClassファイルを利用しないAnonymous Componentsの2種類があります。本文書ではAnonymous Componentsの説明を行い、その後にClassベースComponentsの説明を行います。
本文書公開時はLaravel8を利用して動作確認を行っていましたが、Laravel9、さらにLaravel11でも動作確認を行い記事の更新を重ねています。本文書の内容の範囲ではLaravelのバージョンがアップしても内容は変わっていないのでBlade Componentsは息の長い知識として活用できます。
Laravelの環境構築
laravel newコマンドを使って任意のフォルダにLaravelプロジェクトを作成します。プロジェクト名には任意の名前をつけてください。ここではlarave-component-learnという名前にしています。Laravel11ではlaravel newコマンドを利用することでStarter Kitなどの選択とデーターベースの作成まで行うことができます。
% laravel new laravel-component-learn
_ _
| | | |
| | __ _ _ __ __ ___ _____| |
| | / _` | '__/ _` \ \ / / _ \ |
| |___| (_| | | | (_| |\ V / __/ |
|______\__,_|_| \__,_| \_/ \___|_|
┌ Would you like to install a starter kit? ────────────────────┐
│ No starter kit │
└──────────────────────────────────────────────────────────────┘
┌ Which testing framework do you prefer? ──────────────────────┐
│ Pest │
└──────────────────────────────────────────────────────────────┘
┌ Would you like to initialize a Git repository? ──────────────┐
│ No │
└──────────────────────────────────────────────────────────────┘
//略
┌ Which database will your application use? ───────────────────┐
│ SQLite │
└──────────────────────────────────────────────────────────────┘
プロジェクトが完了したらプロジェクトフォルダに移動してLaravelの開発サーバを起動してください。
% cd laravel-component-learn
% php artisan serve
Starting Laravel development server: http://127.0.0.1:8000
ブラウザで確認するとLaravelの初期ページの画面が表示されます。ブラウザに表示されている画面の内容はresources¥views¥welcome.blade.phpファイルに記述されているのでこのファイルを利用してComponentsの理解を深めていきます。
利用したLaravelのバージョンも確認しておきます。
% php artisan -V
Laravel Framework 11.8.0
welcome.blade.phpファイルを以下のように更新します。Blade Componentsを動作確認する中でスタイルを設定する際に簡単に設定が行えるようにutility classを持つTailwindCSSの最新版をCDN経由で利用しています。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel Components</title>
<!-- Styles -->
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<h1 class="text-2xl">Laravel Components</h1>
</body>
</html>
text-2xlはTailwind CSSが持つutility classの一つで文字の大きさは大きく表示させるclassです。Tailwind CSSが正常に動作している場合には文字が大きく表示されます。何も変化がない時には設定が正常に行われていません。
Blade Componentsとは
Blade Componentsがどのようなものなのか理解するためにはこれまでのBlade TemplatesとBlade Componentsを利用した記述方法を比較することが一番の近道だと思います。Blade Templatesにも慣れていない人にも理解してもらえるようにシンプルなコードを使って比較を行います。
Blade Componentsを使わない場合(従来のBlade)
Blade Componentsを利用しない場合は、@extend, @yield, @sectionといったディレクティブを使ってレイアウトを作成します。resources¥viewsの下にlayoutsフォルダを作成しapp.blade.phpファイルを作成して以下のコードを記述します。@yield, @sectionの場所にapp.blade.phpファイルを利用するBladeファイルからコンテンツが挿入されます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@yield('title')</title>
<!-- Styles -->
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
@section('sidebar')
<p>サイドバーです。</p>
@show
@yield('content')
</body>
</html>
welcome.blade.phpファイルではレイアウトファイルapp.blade.phpを利用するために@extendsディレクティブでapp.blade.phpを指定します。layoutsフォルダの下にapp.blade.phpが保存されているので@extendsで指定するファイルの場所はlayouts.appと記述することができます。
@extends('layouts.app')
app.blade.phpファイルで記述したyieldディレクティブの中にwelcome.blade.phpファイルからコンテンツを挿入したい場合は@sectionディレクティブを利用します。titleタグのようにタグ間に入るコンテンツが短い場合は@sectionの第2引数にテキスト(Laravel Components)を入力することで@yield(‘title’)の部分に入力したテキストが表示されます。
@extends('layouts.app')
@section('title','Laravel Components')
sectionディレクティブでtitleを設定したtittleタグに反映されブラウザのタブに”Laravel Components”が表示されていることが確認できます。
@yield(‘content’)の場所にHTML文などを挿入したい場合は下記のように@section(‘content’)と@endsectionの間に挿入します。先ほどtitleを設定した@sectionと異なり、第2引数を使わない場合は閉じタグの@endsectionが必須となります。ここでは@sectionと@endsectionの中に1行しか記述されていませんが複数行のHTML文を挿入することができます。
@extends('layouts.app')
@section('title','Laravel Components')
@section('content')
<h1 class="text-2xl">Laravel Components</h1>
@endsection
app.blade.phpファイルの@yield(‘content’)の部分にsectionディレクティブのcontentで設定したコンテンツが表示されていることが確認できます。
app.blade.phpファイル側で@section(‘sidebbar’)と@showを使っている箇所があります。これは@yieldと同様にwelcome.blade.phpファイル側で@section(‘sidebar’)を使ってコンテンツを表示させることができます。@yieldsとは異なり@sectionと@showを利用した場合はwelcome.blade.phpに”サイドバーです。”といったコンテンツを継承(渡す)することができます。しかし継承には注意が必要でapp.blade.phpファイル@section(‘sidebar’)で記述したコンテンツ(”サイドバーです。”)を表示させたい場合は@parentディレクティブを記述する必要があります。@parentを利用しない場合はwelcome.blade.phpの@section(‘sidebar’)に記述したコンテンツのみ表示されます。
@extends('layouts.app')
@section('title','Laravel Components')
@section('sidebar')
@parent
<p>サイドバーに追加できます。</p>
@endsection
@section('content')
<h1 class="text-2xl">Laravel Components</h1>
@endsection
ブラウザで確認すると下記のように表示されます。複数のBladeファイルを利用して1つのページを作成することができます。
@parentを利用していない場合も確認しておきます。
@extends('layouts.app')
@section('title','Laravel Components')
@section('sidebar')
<p>サイドバーに追加できます。</p>
@endsection
@section('content')
<h1 class="text-2xl">Laravel Components</h1>
@endsection
ブラウザ上には”サイドバーです。”が表示されません。
Blade Componentsを使う場合
Blade Componentsを利用する場合はresources¥viewsの下にcomponentsフォルダを作成してその下にapp.blade.phpファイルを作成します。Blade Componentsを利用する場合は@yieldディレクティブではなく{{ $slot }}を使います。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel Components</title>
<!-- Styles -->
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
{{ $slot }}
</body>
</html>
次にapp.blade.phpを利用するwelcome.blade.php記述方法は@extendsディレクティブではなくタグを利用します。利用するタグ名はx-{テンプレート名}となります。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
</x-app>
x-appタグの間に記述したコンテンツがapp.blade.phpの{{ $slot }}の中に展開されて表示されます。
これがBlade Componentsの最もシンプルな利用方法です。
x-appタグでx-の後ろにappを入れただけで¥resources¥views¥components¥app.blade.phpファイルが利用できるのはLaravelが自動で¥resources¥views¥componentsにComponentsファイルがあるかチェックして読み込んでくれるためです。componentsフォルダの下にさらにlayoutsフォルダを作成しapp.blade.phpファイルを保存した場合はx-layouts.appとタグの名前が変わります。ルールに沿ってタグ名を設定する必要があります。
welcome.blade.phpファイルのx-appタグに間にコンテンツを記述することでComponentsファイルであるapp.blade.phpの{{ $slot }}に表示されることがわかりました。Blade Componentsを利用しない場合に設定したtitle, sidebarはどのように表示させるか確認していきます。
Blade Componentsでは@yieldsや@sectionディレクティブを利用するのではなくwelcome.blade.phpからのコンテンツを表示させたい部分に{{ $変数名 }}を追加します。変数名は任意の名前をつけることができここでは{{ $title }}, {{ $sidebar }}を追加します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ $title }}</title>
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
</head>
<body>
<p>サイドバーです。</p>
{{ $sidebar }}
{{ $slot }}
</body>
</html>
追加が完了したらコンテンツを渡す側のwelcome.blade.phpファイルを更新します。コンテンツをapp.bladee.phpに渡すwelcome.blade.phpでは、x-slotタグを利用してname属性に変数の名前を指定しタグの中に渡したいコンテンツを入力することでapp.blade.phpファイルの$titleと$sidebarの場所にコンテンツを渡すことができます。welcome.blade.phpファイル側でslotのtitle, sidebarを設定していない場合には”Undefined variable $title”のErrorExceptionが発生してエラー画面が表示されます。
<x-app>
<x-slot name="title">
Laravel Components
</x-slot>
<x-slot name="sidebar">
<p>サイドバーに追加できます。</p>
</x-slot>
<h1 class="text-2xl">Laravel Components</h1>
</x-app>
Blade Componentsを利用することで従来のBlade Templateを利用した方法と同じ内容を表示させることができました。個人的にはBlade Componentsの方が設定がシンプルで初めての人にもわかりやすいように思います。
Blade Componentsの設定方法
Blade Componentsを利用する場合と利用しない場合の違いが理解できたので別のBlade Componentsを作成して理解を深めていきます。冒頭でも説明したようにBlade Componentsを利用する方法には2つの方法があります。最初はAnonymous Componentsを利用します。
Blade Componentsを利用して再利用可能なコンポーネントを作成していきます。
componentsフォルダに新たにalert.blade.phpファイルを作成します。php artisanコマンドで作成することも可能です。その場合はphp artisan mke:componentに–viewオプションをつけて実行します。
% php artisan make:component alert --view
INFO Component created successfully.
作成したAlertコンポーネント(alert.blade.php)には下記を記述します。tailwindcssのcssを適用しています。
<div class="flex justify-between p-4 items-center bg-red-500 text-white">
<div>これはアラートメッセージです。</div>
<button>×</button>
</div>
app.blade.phpファイルは$slotのみに戻しておきます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel Components</title>
<!-- Styles -->
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
{{ $slot }}
</body>
</html>
Alertコンポーネントを利用するためにwelcome.blade.phpファイルにx-alertタグを追加します。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert />
</x-app>
ブラウザで確認すると背景色が赤のメッセージバーが表示されます。
Alertコンポーネントのメッセージバーに表示されているコンテンツはalert.blade.phpファイルに直接記述していますがコンテンツを外側から更新できるようにすることで再利用可能なコンポーネントへと変更します。
$slotを利用した方法
$slotを利用することでAlertコンポーネントのコンテンツを外側から変更することが可能になります。
<div class="flex justify-between p-4 items-center bg-red-500 text-white">
<div>{{ $slot }}</div>
<button>×</button>
</div>
$slotにコンテンツを渡すためにはx-alertタグの間にコンテンツを入力します。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert>これはアラートメッセージです。</x-alert>
</x-app>
ブラウザ上ではAlertコンポーネントに直接コンテンツを入力していた場合と同じ内容が表示されます。
属性を利用した方法
$slotだけではなく属性を利用しpropsとしてコンテンツを渡すことができます。Alertコンポーネントの$slotを$messageに変更します。
<div class="flex justify-between p-4 items-center bg-red-500 text-white">
<div>{{ $message }}</div>
<button>×</button>
</div>
x-alertタグにAlertコンポーネントに記述した変数$messageのmessage部分を属性として追加し表示させたいコンテンツを設定します。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert message="これはアラートメッセージです。" />
</x-app>
属性を利用してもブラウザ上では$slotを利用した場合と全く同じ内容が表示されます。
Laravelの変数を利用した場合
ルーティングファイル内で定義した変数$messageをviewファイルに渡しその変数の中身をAlertコンポーネントに表示させる方法を確認します。コンポーネントとLaravelのデータ連携を行う際に利用することができます。
web.phpファイルを開いてwelcome.blade.phpに変数$messageを渡します。
Route::get('/', function () {
return view('welcome',['message' => 'これはアラートメッセージです。']);
});
Laravel上で定義されている変数を利用する場合はmessage属性の前に:(コロン)をつける必要があります。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert :message="$message" />
</x-app>
ブラウザで確認すると:(コロン)をつけて変数を渡しても表示される内容は変わりません。
初期値を設定する
message属性の初期値は@propsディレクティブを利用して設定することができます。
alert.blade.phpファイルの先頭に@propsディレクティブを追加し配列を使ってmessageに初期値を設定します。配列になっているため複数の属性の初期値を設定したい場合にも対応できます。
@props(['message' => 'このメッセージはデフォルトです。' ])
<div class="flex justify-between p-4 items-center bg-red-500 text-white">
<div>{{ $message }}</div>
<button>×</button>
</div>
初期値を設定するとx-alertタグにmessage属性を設定しない場合は@propsで設定した初期値が表示されます。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert />
</x-app>
ブラウザで確認するとx-alertタグにmessage属性を設定していないのでpropsで設定した初期値が表示されることが確認できます。
属性を設定すると初期値は上書きされて表示されます。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert :message="$message" />
</x-app>
属性で背景色を制御
メッセージの背景色を赤に固定していましたが緊急性のあるメッセージの場合は赤、緊急度のないメッセージには青のようにAlertコンポーネントの外側から背景色を変更する方法を確認していきます。中身のコンテンツだけではなく背景色も変更できればより再利用可能で汎用的なコンポーネントになります。
$type属性を新たに設定して$type属性の値によって背景色が変更できるように変更を行います。{{ }}の中で三項演算子を使って$typeがsuccessの場合はbg-green-500となりsuccess以外はbg-red-500のclassが適用されます。
@props([
'message' => 'このメッセージはデフォルトです。',
'type' => 'success'
])
<div class="flex justify-between p-4 items-center {{ $type=='success' ? 'bg-green-500' : 'bg-red-500' }} text-white">
<div>{{ $message }}</div>
<button>×</button>
</div>
デフォルト値をsuccessにしているのでx-alertタグでtype属性を設定しなくてもbg-green-500が適用されて背景色が緑に変わります。
x-alertタグにtype属性を設定しデフォルト値ではないalertを設定します。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert type="alert" />
</x-app>
alertを設定した場合(success以外の文字列)は背景が赤で表示されます。
赤と緑にしか背景色を設定することができないのでより汎用的にするために@phpディレクティブを使います。@phpディレクティブの中ではphpのコードを記述することができます。
@phpディレクティブで定義した変数を下記のように定義し、利用することができます。
@props([
'message' => 'このメッセージはデフォルトです。',
'type' => 'success'
])
@php
$addClass = 'bg-yellow-500';
@endphp
<div class="flex justify-between p-4 items-center {{ $addClass }} text-white">
<div>{{ $message }}</div>
<button>×</button>
</div>
$addClassでbg-yellow-500を設定しているので背景色は黄色になります。
@phpディレクティブにswitch構文を追加してtypeで渡せれる値によって背景色を変更できるように設定します。@phpディレクティブで関数を利用しているのでaddClass関数を実行する際はカッコが必要となります。
@props([
'message' => 'このメッセージはデフォルトです。',
'type' => 'success'
])
@php
function addClass($type){
$result = '';
switch($type){
case 'success':
$result = 'bg-green-500';
break;
case 'info':
$result = 'bg-blue-200';
break;
case 'alert':
$result = 'bg-red-500';
break;
case 'warning':
$result = 'bg-yellow-500';
break;
defalut:
$result = 'bg-green-500';
}
return $result;
}
@endphp
<div class="flex justify-between p-4 items-center {{ addClass($type) }} text-white">
<div>{{ $message }}</div>
<button>×</button>
</div>
typeにinfoを設定すると薄いブルーが表示されます。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert :message="$message" type="info" />
</x-app>
@phpディレクティブの中で関数を設定していましたが関数を設定せず以下のようにも記述することができます。
@props([
'message' => 'このメッセージはデフォルトです。',
'type' => 'success'
])
@php
switch($type){
case 'success':
$addClass = 'bg-green-500';
break;
case 'info':
$addClass = 'bg-blue-200';
break;
case 'alert':
$addClass = 'bg-red-500';
break;
case 'warning':
$addClass = 'bg-yellow-500';
break;
defalut:
$addClass = 'bg-green-500';
break;
}
@endphp
<div class="flex justify-between p-4 items-center {{ $addClass }} text-white">
<div>{{ $message }}</div>
<button>×</button>
</div>
x-alertタグにclassを設定した場合
class属性をx-alertタグに追加した場合の動作確認も行っておきます。試しに文字のフォントを太くするためにfont-boldを追加してみましょう。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert :message="$message" type="info" class="font-bold" />
</x-app>
x-alertタグにclass=”font-bold”を設定してもブラウザの表示に何も変化はありません。
classを設定する場合はattributesバッグを利用することでx-alertに設定したclassを設定することができます。attributesバッグは$attributesを設定することで利用することができます。$attributesにはx-タグに設定されて属性情報が入っています。
<div {{ $attributes }} class="flex justify-between p-4 items-center {{ addClass($type) }} text-white">
ブラウザのデベロッパーツールのコンソールで要素を確認するとx-alertで設定したclassのfont-boldは設定されていますがalert.blade.phpファイル側で設定したclassが無効になっていることが確認できます。
$attributesのみではclass属性を上書きしてしまいます。上書きをさけるために$attributesのmergeメソッドを利用することでどちらのclassの設定も反映させることができます。つまりx-alertタグで設定したclassとalertコンポーネント内で設定したclassをマージすることができます。
<div {{ $attributes->merge(['class' => 'flex justify-between p-4 items-center '.addClass($type).' text-white']) }}>
ブラウザのデベロッパーツールを見ると既存のclassだけではなくx-alertタグに設定したclassのfont-boldを確認することができ、文字の太さが変更されていることもわかります。
class属性以外の属性をmerge
class以外の属性もmergeを利用することができるのか確認するためにstyle属性を利用します。alertコンポーネントでmergeメソッドの中にstyle属性の設定を行います。classだけではなく複数の属性をmergeする場合は下記のように記述することができます。
<div {{ $attributes->merge([
'class' => 'flex justify-between p-4 items-center '.addClass($type).' text-white',
'style'=> 'font-size:30px;'
])}}>
style属性に設定したfont-size:30pxが反映されて文字のサイズが大きくなります。
classのようにマージができるか確認を行うのでx-alertタグにstyle属性を追加します。font-styleでitalicを設定しています。
<x-alert :message="$message" type="info" class="font-bold" style="font-style:italic" />
ブラウザで確認するとclassのように両方のclassがマージされるのではなくx-alertタグに設定したstyle属性のみ反映されることがわかります。
$attributesのmergeメソッドではclass属性はマージされますがstyle属性を含め、他の属性ではマージは行われずデフォルト値として設定されます。コンポーネントタグ(x-alert)で属性を設定した場合はmergeで設定した値は上書きされます。
ClassベースComponents
これまでに動作確認を行ってきたComponentsはAnonymous Componentsで1つのファイルのみを利用して設定を行うことができました。これから説明を行うClassベースComponentsは2つのファイル(ClassファイルとBladeファイル)を利用してComponentsの処理を記述していきます。
ClassベースComponentsの作成
php artisanコマンドを利用してClassベースComponentsを作成することができます。
% php artisan make:component Alert
Component created successfully.
コマンドを実行すると自動で2つのファイルが作成され、app¥View¥Componentsの下にAlert.phpファイル、resources¥views¥componentsの下にalert.blade.phpファイルが作成されます。
Alert.phpファイルにはconstructorメソッドとrenderメソッドが記述されており、renderメソッドにはcomponets.alertが設定されています。指定しているcomponents.alertがコマンド実行時に自動作成されるalert.blade.phpファイルに対応します。
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component
{
public function __construct()
{
//
}
public function render()
{
return view('components.alert');
}
}
alert.blade.phpはdiv要素のみ記述されています。
<div>
<!-- The whole future lies in uncertainty: live immediately. - Seneca -->
</div>
alert.blade.phpファイルを下記のように更新し、x-alertタグでブラウザ上にコンテンツを表示します。
<div class="flex justify-between p-4 items-center bg-red-500 text-white">
<div>これはアラートメッセージです。</div>
<button>×</button>
</div>
welcome.blade.phpファイルにx-alertタグを追加します。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert />
</x-app>
ブラウザ上にメッセージが表示されます。
x-alertタグの使い方はAnonymous Componentの場合と同じですが、ClassベースComponentsの場合はx-alertタグからLaravelが自動でapp¥View¥Componentsの下にあるAlert.phpを見つけて処理を行ってくれます。Alert.phpファイルがない場合はAnonymous Componentsとしてresources¥views¥componentsにあるalert.blade.phpファイルが利用されます。
$slotを利用した方法
$slotを利用してx-alertタグの間に記述したコンテンツを表示させます。alert.blade.phpファイルに$slotを追加します。
<div class="flex justify-between p-4 items-center bg-red-500 text-white">
<div>{{ $slot }}</div>
<button>×</button>
</div>
welcome.blade.phpファイルのx-alertタグの間にコンテンツを記述します。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert>これはアラートメッセージです。</x-alert>
</x-app>
x-alertタグに記述した内容が表示されます。ClassベースComponentでもAnonymous Componentでも$slotの利用方法は変わりません。
属性を利用した方法
$slotではなく属性を利用した場合にコンテンツが表示されるか確認します。Anonymous Componentで行った方法と同じ方法で確認します。
alert.blade.phpファイルの$slotを$messageに変更します。
<div class="flex justify-between p-4 items-center bg-red-500 text-white">
<div>{{ $message }}</div>
<button>×</button>
</div>
x-alertタグにmessage属性を追加しコンテンツを設定します。
<x-app>
<h1 class="text-2xl">Laravel Components</h1>
<x-alert message="これはアラートメッセージです。" />
</x-app>
ブラウザで確認すると”ErrorException Undefined variable: message”が表示さmessageの内容をAlertコンポーネントに渡すことができません。
ClassベースComponentではClassファイルのAlert.phpにmessage変数を定義する必要があります。
public $message;
public function __construct($message)
{
$this->message = $message;
}
public function render()
{
return view('components.alert');
}
定義した$messageはrender関数のviewメソッドで変数としてviewに渡す必要はありません。
定義後にはエラーが解消されmessageに設定したコンテンツが表示されます。
Laravelの変数を利用した場合
ルーティングファイルweb.phpからviewファイルに対してmessage変数を渡した場合はx-alertタグのmessage属性の前にコロンをつけることで渡されたmessage変数の内容を表示させることができます。これはAnonymous Componentと同じ方法です。
Route::get('/', function () {
return view('welcome',['message' => 'これはルーティングからのアラートメッセージです。']);
});
<x-alert :message="$message" />
ブラウザで確認するとweb.phpファイルでviewに渡されたmessage変数の内容を表示することができます。
初期値を設定する
Anonymous Componentは初期値を与えたい場合はpropsを利用することができました。Anonymous Componentと同じ方法で初期値が設定できるか確認します。
ClassベースComponentsでは@propsでmessageに初期値を与え、x-alertタグからmessage属性を削除するとエラーが発生し@propsでは初期値の設定を行うことができません。
@props([
'message' => 'このメッセージはデフォルトです。'
])
<div class="flex justify-between p-4 items-center bg-red-500 text-white">
<div>{{ $message }}</div>
<button>×</button>
</div>
初期値の設定は@propsではなくAlert.phpファイルで行います。constructorメソッドの引数で$messageの初期値を設定します。
public function __construct($message="このメッセージはデフォルトです。")
{
$this->message = $message;
}
ブラウザで確認するとconstructorメソッドで設定した初期値が表示されます。
x-alertタグにmessage属性を追加してコンテンツを設定することで初期値を上書きすることができます。
属性で背景色を制御
type属性を使ってalertコンポーネントの背景色を変更できるように設定を行っていきます。属性を追加した場合はAlert.phpファイルで変数を定義する必要があります。$typeの初期値は”success”に設定しています。
public $message;
public $type;
public function __construct($message="このメッセージはデフォルトです。",$type="success")
{
$this->message = $message;
$this->type = $type;
}
alert.blade.phpファイルでは$typeの値によって背景色が変わるように設定を行います。
<div class="flex justify-between p-4 items-center {{ $type=='success' ? 'bg-green-500' : 'bg-red-500' }} text-white">
<div>{{ $message }}</div>
<button>×</button>
</div>
Alert.phpファイルでは$type変数に初期値を与えているのでx-alertタグではtype属性を設定せずブラウザで確認します。
x-alertタグでtypeにsuccess以外の値を設定します。
<x-alert message="これはアラートメッセージです。" type="error" />
typeの値をerrorに設定したので背景色が赤で表示されます。
属性はAlert.phpで定義する必要がありますが、それ以外の設定はAnonymous Componentと同じです。
2色以外の背景色を設定したい場合のコードはAlert.phpファイルの中に記述します。switch構文で$typeの値により背景色のclassを戻すaddClass関数を追加します。
public function addClass(){
$result = '';
switch($this->type){
case 'success':
$result = 'bg-green-500';
break;
case 'info':
$result = 'bg-blue-200';
break;
case 'alert':
$result = 'bg-red-500';
break;
case 'warning':
$result = 'bg-yellow-500';
break;
defalut:
$result = 'bg-green-500';
}
return $result;
}
alert.blade.phpファイルにaddClass関数を追加します。addClassの後にカッコをつけるのを忘れないでください。引数は必要ありません。
<div class="flex justify-between p-4 items-center {{ $addClass() }} text-white">
<div>{{ $message }}</div>
<button>×</button>
</div>
x-alertタグのtype属性の値を変更することで背景色を変更することができます。
<x-alert message="これはアラートメッセージです。" type="warning" />
type属性をwarningに設定すると以下のように表示されます。
Anonymous Componentでは属性の初期値を@props、PHPのコードを@phpディレクティブを利用して行っていましたが、ClassベースComponentではそれらの処理をすべてAlert.phpファイルの中で行うことがわかりました。
ClassベースComponentでも$attributes, $attributes->mergeを利用することができます。設定方法はAnonymous Componentで同じで説明済なので”x-alertタグにclassを設定した場合”, “class属性以外の属性をmerge”を参考にしてください。
Componentsのサービスプロバイダーへの登録
php artisan make:componentコマンドで作成したAlert.phpファイルを利用する場合はx-alertタグを使っていましたが、ClassベースComponentはClassをサービスプロパイダーに登録することでタグ名を変更することできます。
app¥Providers¥AppServiceProvider.phpファイルを開いてbootメソッドに下記を追加し、BladeとAlertをimportします。
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Blade;
use App\View\Components\Alert;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
//
}
public function boot()
{
Blade::component('package-alert', Alert::class);
}
}
登録が完了するとx-package-alertタグを利用してalertコンポーネントを利用することができます。
<x-package-alert message="これはアラートメッセージです。" type="warning" />
Blade TemplateとBlade Componentsの違いまたBlade ComponentsにはClass ベースComponentとAnonymous Componentがあり設定方法が異なることも理解できたかと思います。
認証機能のLaravel BreezeにもBlade Componentsが使われていますが本文書の内容を理解できればレイアウトの構成、ファイル構成も理解することができます。次回LaravelのBladeファイルでページを作成する場合はBlade Componentsを利用してレイアウトの作成を行ってみてください。