LoginSignup
17
13

More than 5 years have passed since last update.

bladeのcomponent化による再利用

Last updated at Posted at 2019-03-26

最近 blade を使ったhtmlのコンポーネント化について調べたのでまとめます。
Laravel公式のbladeテンプレートのセクションにも記載があり、実用できそうでした。

サンプル

コンポーネントを/resources/views/components/attribute.blade.phpから呼び出すサンプルです。

resources/views/sample.blade.php

<div class="attribute-wrapper">
    @component('components.attribute',
                ['attributeName'=>__("氏名"),
                    'required'=>true,
                    'attributeInfo'=> __("名前を入力してください")])
    @endcomponent
</div>

/resources/views/components/attribute.blade.php

<div class="attribute-name">
    <span>{{ $attributeName }}</span>
    <div class="d-flex justify-content-between position-relative">
        @if($required)
        <div class="required ">{{ __('必須') }}</div>
        @endif
        <i class="fas fa-info-circle attribute-info-mark"></i>
        <p class="attribute-info">{{ $attributeInfo }}</p>

    </div>
</div>

cssとhtmlの記述をbladeで完結させたい

コンポーネント化をすすめていく中で、cssとhtmlの記述をbladeで完結させたいと思いつきました。
調べたところ@ push ディレクティブと、@ stackディレクティブを使うと
pushしたテンプレートをstackで取り出すことができるようです。

スタック
Bladeはさらに、他のビューやレイアウトでレンダできるように、名前付きのスタックへ内容を退避できます。子ビューで必要なJavaScriptを指定する場合に、便利です。

@push('scripts')
    <script src="/example.js"></script>
@endpush

必要なだけ何回もスタックをプッシュできます。スタックした内容をレンダするには、@stackディレクティブにスタック名を指定してください。

<head>
    <!-- Headの内容 -->

    @stack('scripts')
</head>

laravel5.8公式ドキュメント(https://readouble.com/laravel/5.8/ja/blade.html)

コンポーネントのcssが複数回呼び出される

stackに登録したcssを呼び出すと、コンポーネントが複数回呼び出されている場合、複数の同じcssが登録されてしまいました。
解決方法として、Bladeファサードを使い、同一コンポーネントからの同じ要素のpushを防ぐ独自のディレクティブ pushonceを作成することで解決する方法を記載します。

1. pushonceディレクティブの登録

App\Providers\AppServiceProvider

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
        \Blade::directive('pushonce', function ($expression) {
            $var = '$__env->{"__pushonce_" . md5(__FILE__ . ":" . __LINE__)}';

            return "<?php if(!isset({$var})): {$var} = true; \$__env->startPush({$expression}); ?>";
        });

        \Blade::directive('endpushonce', function ($expression) {
            return '<?php $__env->stopPush(); endif; ?>';
        });
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

2. component毎にcssをpushする

resources\views\components\operations.blade.php

div class="operations-container status-bar">
    {{ $slot }}
</div>

@pushonce('css')
    <style>
        .operations-container{
            display: flex;
            /* justify-content: space-evenly; */
            flex-flow: row wrap;
            align-content: space-around;
        }
    </style>
@endpushonce

pushonceの呼び出し方は、pushと全く同じです。

3. stackで css を呼び出す。

resources\views\layouts\app.blade.php


    <body>
       <main id="app">
            <div class="main-container">
                @yield('content')  
            </div>
        </main>
    </body>
    @stack('css') 

stackは通常の通りの呼び出しです。
これでコンポーネントのcssの重複呼び出しはなくなりました。

以上です。

17
13
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
13