良いかどうかはともかく、そういう使い方もできるなと思ったネタ。なお 5.5 を使ってます。
普通に @extends
を使えば次のようになりますが、
layout.blade.php
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Laravel - @yield('title')</title>
</head>
<body>
<header>
@section('header')
<h1>Laravel</h1>
@show
</header>
<main>
@yield('content')
</main>
</body>
</html>
home.blade.php
@extends('layout')
@section('title', 'Home')
@section('header')
@parent
<h2>Home</h2>
@endsection
@section('content')
<p>ここは Home のコンテンツです</p>
@endsection
これを @component
を使って次のようにします。
layout.blade.php
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Laravel - {{ $title }}</title>
</head>
<body>
<header>
{{ $header }}
</header>
<main>
{{ $content }}
</main>
</body>
</html>
home.blade.php
@component('layout', ['title' => 'Home'])
@slot('header')
{{-- @parent--}}
<h1>Laravel</h1>
<h2>Home</h2>
@endslot
@slot('content')
<p>ここは Home のコンテンツです</p>
@endslot
@endcomponent
ほぼ同じことが出来ますが、次のような違いがあります。
-
@extends
で使える@parent
に相当するものが@component
にはない -
@extends
ではビューにアサインした変数がレイアウトテンプレートでも使用できる-
@component
だと明示的指定しないとレイアウトテンプレートに変数が渡されない
-
前者はあまり使う機会がない(Smarty や Twig にも同じような機能あるけどほとんど使った試しがない)のと、後者は個別のテンプレート用にアサインしたつもりの変数を、全体で共通に使われるレイアウトのテンプレートで使ってしまって、この変数どっから来たんや・・・みたいなのを避けることができてメリットにも感じます。
もし @component
ですべての変数を渡したければ次のようにもできそうですし。
home.blade.php
@component('layout', get_defined_vars())
{{-- snip --}}
@endcomponent
さいごに
たいていのテンプレートエンジンにある include
や extends
の機能、ビューにアサインされた変数が自動的にすべて引き渡されると include
や extends
の先のテンプレートでどこから来たのかわかりにくい変数が使われてしまうことがあります。
Blade の @component
なら変数は明示的に渡す必要があって間違いが起きにくいので、@include
や @extends
をすべて置き換えてしまっても良いのでは、と思いましたが・・・
@component
を @extends
のように使うのは @component
の本来の用途違うだろうので知らずに見ると混乱しそうで余計判りにくいかな。。。実際他の人が @component
をこのような使い方をしていて何だこれはと思ったわけですけど(それでこの使い方を知った)