#05 Laravel基礎
Bladeコンポーネントを使いこなす
Bladeの復習と次のステップ
基礎シリーズでは @if, @foreach, @extends, @yield を学びました。このシリーズでは再利用可能なUI部品を作るための Bladeコンポーネント? HTMLの部品をクラスまたはファイルとして切り出す仕組み。`<x-button>`のように使える再利用可能なUI部品を作れる。 と、より高度なテンプレート技術を扱います。
匿名コンポーネント(ファイルだけで作る)
最もシンプルなBladeコンポーネントは、resources/views/components/ にBladeファイルを置くだけで作れます。
# components フォルダを作成し、ファイルを配置
# (コマンドでの自動生成もできる)
php artisan make:component Alert --view
resources/views/components/alert.blade.php が生成されます。
{{-- 📁 resources/views/components/alert.blade.php --}}
<div class="alert alert-{{ $type ?? 'info' }}">
{{ $slot }}
</div>
呼び出し方
{{-- 📁 resources/views/posts/index.blade.php --}}
<x-alert type="success">
投稿を保存しました!
</x-alert>
<x-alert type="danger">
エラーが発生しました。
</x-alert>
<x-コンポーネント名> のタグで呼び出せます。タグの中身が $slot に渡されます。
クラスを持つコンポーネント
ロジックが必要なコンポーネントはクラスとセットで作ります。
php artisan make:component UserCard
2つのファイルが生成されます。
<?php
// 📁 app/View/Components/UserCard.php
namespace App\View\Components;
use App\Models\User;
use Illuminate\View\Component;
class UserCard extends Component
{
public function __construct(
public User $user // ← ビューに自動で渡される
) {}
public function render()
{
return view('components.user-card');
}
}
{{-- 📁 resources/views/components/user-card.blade.php --}}
<div class="user-card">
<img src="{{ $user->avatar_url }}" alt="{{ $user->name }}">
<h3>{{ $user->name }}</h3>
<p>{{ $user->email }}</p>
</div>
呼び出すときはモデルを渡します。
{{-- 📁 resources/views/users/index.blade.php --}}
@foreach ($users as $user)
<x-user-card :user="$user" />
@endforeach
:user="$user" のように : を付けると PHP の変数を渡せます。
名前付きスロット
$slot は1つだけですが、名前付きスロットを使うと複数の差し込み口を作れます。
{{-- 📁 resources/views/components/card.blade.php --}}
<div class="card">
<div class="card-header">
{{ $header }} {{-- 名前付きスロット --}}
</div>
<div class="card-body">
{{ $slot }} {{-- デフォルトスロット --}}
</div>
<div class="card-footer">
{{ $footer ?? '' }} {{-- 省略可能なスロット --}}
</div>
</div>
{{-- 使い方 --}}
<x-card>
<x-slot:header>
<h2>投稿一覧</h2>
</x-slot:header>
{{-- ここがデフォルト $slot --}}
<p>投稿内容がここに入ります。</p>
</x-card>
@stack と @push でスクリプトを整理する
ページごとに追加したい CSS や JavaScript を、レイアウトの特定の場所にまとめて出力する仕組みです。
レイアウトに @stack を定義します。
{{-- 📁 resources/views/layouts/app.blade.php --}}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="/css/app.css">
@stack('styles') {{-- ← ページごとのCSSをここに出力 --}}
</head>
<body>
@yield('content')
<script src="/js/app.js"></script>
@stack('scripts') {{-- ← ページごとのJSをここに出力 --}}
</body>
</html>
子ビューから @push で追加します。
{{-- 📁 resources/views/posts/edit.blade.php --}}
@extends('layouts.app')
@push('styles')
<link rel="stylesheet" href="/css/editor.css">
@endpush
@section('content')
<div id="editor">...</div>
@endsection
@push('scripts')
<script src="/js/editor.js"></script>
@endpush
カスタムディレクティブ
@if, @foreach のような独自の @xxx ディレクティブを作れます。
// 📁 app/Providers/AppServiceProvider.php
use Illuminate\Support\Facades\Blade;
public function boot(): void
{
// @admin〜@endadmin : 管理者だけ表示するディレクティブ
Blade::directive('admin', function () {
return "<?php if(auth()->check() && auth()->user()->role === 'admin'): ?>";
});
Blade::directive('endadmin', function () {
return "<?php endif; ?>";
});
}
使い方:
@admin
<a href="/admin/dashboard">管理画面へ</a>
@endadmin
まとめ
resources/views/components/にファイルを置くだけで匿名コンポーネントが作れる<x-コンポーネント名>で呼び出す- クラス付きコンポーネントはロジックをPHPクラスに書ける
@stack/@pushでページごとのCSS・JSを整理できるBlade::directive()でカスタムディレクティブを定義できる
次回はEloquentのリレーションを深掘りします。