> For the complete documentation index, see [llms.txt](https://learnphp.gitbook.io/learnphp/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://learnphp.gitbook.io/learnphp/laravel-advanced/blade-components-for-your-layout-full-ok.md).

# Blade components for your layout full (ok)

Full Doc: <https://laravel.com/docs/9.x/blade#layouts-using-components>

### Ví dụ đã triển khai dùng để làm mẫu

Source code tham khảo&#x20;

{% file src="/files/EoLkFXM2Nza1PsJNdroY" %}

### V1. List

<figure><img src="/files/vykxMx0dYGmEcqrYjHqV" alt=""><figcaption></figcaption></figure>

C:\xampp8\htdocs\testauth\resources\views\banner\index.blade.php

```
@extends('layouts.main')
@section('class','banner')
@section('main')
<div class="tab-content rounded-bottom bg-white">
  <div class="tab-pane p-3 active preview text-center" role="tabpanel">
    <table class="table table-bordered">
      <x-tables.banner.thead>
        <x-tables.banner.th />
      </x-tables.banner.thead>
      <x-tables.banner.tbody>
        <x-tables.banner.tr :datas=$banners :type=$type />
      </x-tables.banner.tbody>
    </table>
    {!! $banners->links() !!}
  </div>
</div>
@endsection
```

C:\xampp8\htdocs\testauth\resources\views\components\tables\banner\thead.blade.php

```
<thead class="bg-dark text-white">
  <tr>
    {{ $slot }}
  </tr>
</thead>
```

C:\xampp8\htdocs\testauth\resources\views\components\tables\banner\th.blade.php

```
@props([
"width"=> "150px",
"labels" => 
  [
    "ID"=> [
      "breakwidth" => false,
      "breakcolspan" => false,
      "colspan"=> 2
    ],
    "表示順"=> [
      "breakwidth" => false,
      "breakcolspan" => false,
      "colspan"=> 2
    ],
    "登録内容"=> [
      "breakwidth" => true,
      "breakcolspan" => true,
      "colspan"=> 2
    ]
  ]
])
@foreach ($labels as $label => $value)
  <th scope="col" @if(!$value['breakwidth'])width={{$width}}@endif @if($value['breakcolspan']) colspan={{$value['colspan']}}@endif>{{ $label }}</th>
@endforeach
```

C:\xampp8\htdocs\testauth\resources\views\components\tables\banner\tbody.blade.php

```
<tbody>
  {{ $slot }}
</tbody>
<style>
  .banner__box h3 {
    margin-bottom: 20px;
  }
  .banner__tag {
    margin-bottom: 60px;
  }
  .banner__time span {
    font-weight: 700;
  }
</style>
```

C:\xampp8\htdocs\testauth\resources\views\components\tables\banner\tr.blade.php

```
@foreach ($datas as $data)
<tr>
  <td>{{ $data['id'] }}</td>
  <td>{{ $data['sort_no'] }}</td>
  <td width="300px">
    <img class="img-fluid" src="{{ $data['image_url'] }}" alt="Image">
  </td>
  <td class="text-start banner__box">
    <p>{{ $data['publish_start'] }}　～　{{ $data['publish_end'] }}</p>
    <h3><a href="{{ route('banner.type.edit.id',[$type,$data['id']]) }}">{{ $data['title'] }}</a></h3>
    <x-tables.tags.group>
      <x-tables.tags.tag />
    </x-tables.tags.group>
    <x-tables.times.group>
      <x-tables.times.create-update />
    </x-tables.times.group>
  </td>
</tr>
@endforeach
```

C:\xampp8\htdocs\testauth\resources\views\components\tables\tags\group.blade.php

```
<div {{ $attributes->merge(['class' => 'd-flex flex-wrap banner__tag']) }}>
  {{ $slot }}
</div>
```

C:\xampp8\htdocs\testauth\resources\views\components\tables\tags\tag.blade.php

```
@props([
  'tags' => ["レギュラー","レギュラー"]
])
@foreach ($tags as $tag)
  <span {{ $attributes->merge(['class' => 'rounded-pill border px-2 me-2 mb-2']) }}>{{ $tag }}</span>
@endforeach
```

C:\xampp8\htdocs\testauth\resources\views\components\tables\times\group.blade.php

```
<div {{ $attributes->merge(['class' => 'd-flex justify-content-between banner__time']) }}>
  {{ $slot }}
</div>
```

C:\xampp8\htdocs\testauth\resources\views\components\tables\times\create-update.blade.php

```
@props([
  'datas' => ["登録日時"=>"2022-12-12 07:18:06","更新日時"=>"2022-12-12 07:18:06"]
])
@foreach ($datas as $label => $data)
  <small>
    <span {{ $attributes->merge(['class' => 'start me-1']) }}">{{ $label }}</span>
    {{ $data }}
  </small>
@endforeach
```

### V2. Edit

<figure><img src="/files/gPdjywz18A8HHzVgA7wG" alt=""><figcaption></figcaption></figure>

C:\xampp8\htdocs\testauth\resources\views\components\inputs\group.blade.php

```
@props([
  'label', 
  'for',
  'class' => 'btn-dark'
])
<div class="input-group">
  <label for="{{ $for }}" {{ $attributes->merge(['class' => "btn $class  px-5 rounded-2"]) }}>
    {{ $label }}
  </label>
  {{ $slot }}
</div>
```

C:\xampp8\htdocs\testauth\resources\views\components\inputs\text.blade.php

```
@props([
'for',
'type' => 'text',
'value' => '',
'width' => '250px'
])
<input id="{{ $for }}" name="{{ $for }}" style="width:{{$width}};" type="{{ $type }}" value="{{ $value }}" {{ $attributes->merge(['class' => 'form-control']) }} />
```

C:\xampp8\htdocs\testauth\resources\views\components\selects\group.blade.php

```
@props([
  'for' => 'target',
  'width' => '250px'
])
<select style="width:{{$width}};" {{ $attributes->merge(['class' => 'form-select']) }} aria-label="Default select example" id="{{ $for }}" name="{{ $for }}">
  {{ $slot }}
</select>
```

C:\xampp8\htdocs\testauth\resources\views\components\checkboxs\group.blade.php

```
<div {{ $attributes->merge(['class' => 'text-start']) }}>
  {{ $slot }}
</div>
```

C:\xampp8\htdocs\testauth\resources\views\components\checkboxs\checkbox.blade.php

```
@props([
  "name" => 'checks',
  "checkboxs" => ["ゴールド"=>1,"レギュラー"=>2,"ジュニア" => 3, "カジュアルレギュラー"=>4,"無料"=>5,"アカデミー"=>6],
])
<div {{ $attributes->merge(['class' => 'form-check d-inline-flex']) }}>
  @foreach ($checkboxs as $label => $value)
    <input class="form-check-input" type="checkbox" name="{{ $name }}" id="{{ $name . $value }}" value="{{ $value }}">
    <label {{ $attributes->merge(['class' => 'form-check-label me-5 ms-2']) }} for="{{ $name . $value }}">ゴールド</label>
  @endforeach
</div>
```

C:\xampp8\htdocs\testauth\resources\views\components\buttons\group.blade.php

```
<div {{ $attributes->merge(['class' => 'form-check form-check-block text-center']) }}>
  {{ $slot }}
</div>
```

C:\xampp8\htdocs\testauth\resources\views\components\buttons\button.blade.php

```
@props([
  "type" => "submit",
  "width" => "120px",
  "label" => "登録"
])
<button type="{{ $type }}" style="width: {{ $width }};" {{ $attributes->merge(['class' => 'btn']) }}>{{ $label }}</button>
```

### 1. Blade Components for your Layout

<figure><img src="/files/3olAc6hAjd7fb27iuhrG" alt=""><figcaption></figcaption></figure>

```
php artisan make:component Layout
```

C:\xampp8\htdocs\testauth\app\View\Components\Layout.php

```php
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Layout extends Component
{
  /**
   * Create a new component instance.
   *
   * @return void
   */
  public function __construct()
  {
    //
  }
  /**
   * Get the view / contents that represent the component.
   *
   * @return \Illuminate\Contracts\View\View|\Closure|string
   */
  public function render()
  {
    return view('components.layout');
  }
}
```

C:\xampp8\htdocs\testauth\resources\views\components\layout.blade.php

```
<!-- /views/components/layout.blade.php -->
<!DOCTYPE html>
<html>
<head>
  @yield('scripts')
</head>
<body>
  @yield('content')
</body>
</html>
```

C:\xampp8\htdocs\testauth\resources\views\welcome.blade.php

```
<x-layout>
  @section('scripts')
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
  @endsection
  @section('content')
    <div>My Page content is here</div>
  @endsection
</x-layout>
```

### 2. Named Slots

<figure><img src="/files/4vAbb4emaojQ48rScrFO" alt=""><figcaption></figcaption></figure>

C:\xampp8\htdocs\testauth\app\View\Components\Layout.php

```php
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Layout extends Component
{
  /**
   * Create a new component instance.
   *
   * @return void
   */
  public function __construct()
  {
    //
  }
  /**
   * Get the view / contents that represent the component.
   *
   * @return \Illuminate\Contracts\View\View|\Closure|string
   */
  public function render()
  {
    return view('components.layout');
  }
}
```

C:\xampp8\htdocs\testauth\resources\views\components\layout.blade.php

```
<!-- /views/components/layout.blade.php -->
<!DOCTYPE html>
<html>
<head>
  {{ $scripts }}
</head>
<body>
  {{ $slot }}
</body>
</html>
```

C:\xampp8\htdocs\testauth\resources\views\welcome.blade.php

```
<x-layout>
  <x-slot name="scripts">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
  </x-slot>
  <div>My Page content is here</div>
</x-layout>
```

### 3. Renderless Blade components

<figure><img src="/files/LCD7uu8KNNIw4ynafrtu" alt=""><figcaption></figcaption></figure>

C:\xampp8\htdocs\testauth\app\View\Components\Section.php

```php
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Section extends Component
{
    /**
     * Create a new component instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }
    /**
     * Get the view / contents that represent the component.
     *
     * @return \Illuminate\Contracts\View\View|\Closure|string
     */
    public function render()
    {
      return function ($componentData) {
        return <<<BLADE
            @section("{$componentData['attributes']->get('name')}")
                {$componentData['slot']}
            @endsection
        BLADE;
    };
    }
}

```

C:\xampp8\htdocs\testauth\app\View\Components\Layout.php

```php
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Layout extends Component
{
  /**
   * Create a new component instance.
   *
   * @return void
   */
  public function __construct()
  {
    //
  }
  /**
   * Get the view / contents that represent the component.
   *
   * @return \Illuminate\Contracts\View\View|\Closure|string
   */
  public function render()
  {
    return view('components.layout');
  }
}
```

C:\xampp8\htdocs\testauth\resources\views\welcome.blade.php

```
<x-layout>
  <x-section name="scripts">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
  </x-section>
  <div>My Page content is here</div>
</x-layout>
```

### 4. Props

<figure><img src="/files/RAbtJH3kx2hmRZ0k6kaB" alt=""><figcaption></figcaption></figure>

C:\xampp8\htdocs\testauth\resources\views\welcome.blade.php

```
<x-layout>
  <x-section name="scripts">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
  </x-section>
  <div>My Page content is here</div>
  @props(['disabled' => true])
  <input {{ $disabled ? 'disabled' : '' }} {!! $attributes->merge(['class' => 'rounded-md shadow-sm border-gray-300'])
  !!}>
</x-layout>
```

### 5. Quick Introduction to Anonymous Blade Components In [Laravel 7](https://www.twilio.com/blog/introduction-anonymous-blade-components-laravel-7)

### 5.1. Giao diện thường

<figure><img src="/files/EM89V9avmbmSsUdkHFIC" alt=""><figcaption></figcaption></figure>

C:\xampp8\htdocs\testauth\routes\web.php

```php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
  return view('profile');
});
Route::get('profile', function () {
  return view('profile');
});
```

C:\xampp8\htdocs\testauth\resources\views\layouts\main.blade.php

```
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Laravel 7 Blade Components</title>
  <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
</head>
<body class="h-screen w-screen flex items-center justify-center">
  @yield('content')
</body>
</html>
```

C:\xampp8\htdocs\testauth\resources\views\profile.blade.php

```php
@extends('layouts.main')
@section('content')
<form style=" width: 50%; ">
  <div>
    <div>
      <h3 class="text-lg leading-6 font-medium text-gray-900">
        Personal Information
      </h3>
    </div>
    <div class="mt-6 sm:mt-5">
      <div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
        <label for="first_name" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
          First name
        </label>
        <div class="mt-1 sm:mt-0 sm:col-span-2">
          <div class="rounded-md shadow-sm">
            <input id="first_name"
              class="bg-white border border-gray-200 py-2 px-3 rounded-lg w-full block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
          </div>
        </div>
      </div>
      <div class="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
        <label for="last_name" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
          Last name
        </label>
        <div class="mt-1 sm:mt-0 sm:col-span-2">
          <div class="rounded-md shadow-sm">
            <input id="las_name"
              class="bg-white border border-gray-200 py-2 px-3 rounded-lg w-full block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
          </div>
        </div>
      </div>
      <div class="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
        <label for="email" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
          Email address
        </label>
        <div class="mt-1 sm:mt-0 sm:col-span-2">
          <div class="mt-1 sm:mt-0 sm:col-span-2">
            <div class="rounded-md shadow-sm">
              <input id="email" type="email"
                class="bg-white border border-gray-200 py-2 px-3 rounded-lg w-full block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
            </div>
          </div>
        </div>
      </div>
      <div class="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
        <label for="street_address" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
          Street address
        </label>
        <div class="mt-1 sm:mt-0 sm:col-span-2">
          <div class="rounded-md shadow-sm">
            <input id="street_address"
              class="bg-white border border-gray-200 py-2 px-3 rounded-lg w-full block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
          </div>
        </div>
      </div>
      <div class="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
        <label for="city" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
          City
        </label>
        <div class="mt-1 sm:mt-0 sm:col-span-2">
          <div class="rounded-md shadow-sm">
            <input id="city"
              class="bg-white border border-gray-200 py-2 px-3 rounded-lg w-full block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
          </div>
        </div>
      </div>
      <div class="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
        <label for="state" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
          State / Province
        </label>
        <div class="mt-1 sm:mt-0 sm:col-span-2">
          <div class="rounded-md shadow-sm">
            <input id="state"
              class="bg-white border border-gray-200 py-2 px-3 rounded-lg w-full block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
          </div>
        </div>
      </div>
      <div class="mt-6 sm:mt-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
        <label for="zip" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
          ZIP / Postal
        </label>
        <div class="mt-1 sm:mt-0 sm:col-span-2">
          <div class="rounded-md shadow-sm">
            <input id="zip"
              class="bg-white border border-gray-200 py-2 px-3 rounded-lg w-full block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class="mt-8 border-t border-gray-200 pt-5">
    <div class="flex justify-end">
      <span class="ml-3 inline-flex rounded-md shadow-sm">
        <button type="submit"
          class="inline-flex justify-center py-2 px-4 border border-transparent text-sm leading-5 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 transition duration-150 ease-in-out">
          Save
        </button>
      </span>
    </div>
  </div>
</form>
@endsection
```

### 5.2. Giao diện dùng Balde Components

C:\xampp8\htdocs\testauth\routes\web.php

```php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
  return view('profile');
});
Route::get('profile', function () {
  return view('profile');
});
```

C:\xampp8\htdocs\testauth\resources\views\profile.blade.php

```php
@extends('layouts.main')
@section('content')
<form style=" width: 50%; ">
  <div>
    <div>
      <h3 class="text-lg leading-6 font-medium text-gray-900">
        Personal Information
      </h3>
    </div>
    <div class="space-y-6 sm:mt-5">
      <x-inputs.group label="First Name" for="first_name">
        <x-inputs.text for="first_name" />
      </x-inputs.group>
      <x-inputs.group label="Last Name" for="last_name">
        <x-inputs.text for="last_name" />
      </x-inputs.group>
      <x-inputs.group label="Email address" for="email">
        <x-inputs.text for="email" type="email" />
      </x-inputs.group>
      <x-inputs.group label="Street address" for="street_address">
        <x-inputs.text for="street_address" />
      </x-inputs.group>
      <x-inputs.group label="City" for="city">
        <x-inputs.text for="city" />
      </x-inputs.group>
      <x-inputs.group label="State" for="state">
        <x-inputs.text for="state" />
      </x-inputs.group>
      <x-inputs.group label="Zip" for="zip">
        <x-inputs.text for="zip" />
      </x-inputs.group>
    </div>
  </div>
  <div class="mt-8 border-t border-gray-200 pt-5">
    <div class="flex justify-end">
      <span class="ml-3 inline-flex rounded-md shadow-sm">
        <button type="submit"
          class="inline-flex justify-center py-2 px-4 border border-transparent text-sm leading-5 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 transition duration-150 ease-in-out">
          Save
        </button>
      </span>
    </div>
  </div>
</form>
@endsection
```

C:\xampp8\htdocs\testauth\resources\views\components\inputs\group.blade.php

```php
@props(['label', 'for'])
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
  <label for="{{ $for }}" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
    {{ $label }}
  </label>
  <div class="mt-1 sm:mt-0 sm:col-span-2">
    {{ $slot }}
  </div>
</div>
```

C:\xampp8\htdocs\testauth\resources\views\components\inputs\text.blade.php

```php
@props([
'for'
])
<div class="rounded-md shadow-sm">
  <input id="{{ $for }}" class="bg-white border border-gray-200 py-2 px-3 rounded-lg w-full block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5" />
</div>
```

<figure><img src="/files/KTWv10HvAsj77UWlvDFp" alt=""><figcaption></figcaption></figure>

### 5.3 Passing In Default Data

<figure><img src="/files/iL9S8ejDb5whVswL7RJZ" alt=""><figcaption></figcaption></figure>

C:\xampp8\htdocs\testauth\routes\web.php

```php
<?php
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
  $data = [
    'first_name' => 'Shane',
    'last_name' => 'Rosenthal',
    'email' => 'srosenthal82@gmail.com',
  ];
  return view('profile', compact('data'));
});
Route::get('profile', function () {
  return view('profile');
});
```

C:\xampp8\htdocs\testauth\resources\views\profile.blade.php

```php
@extends('layouts.main')
@section('content')
<form style=" width: 50%; ">
  <div>
    <div>
      <h3 class="text-lg leading-6 font-medium text-gray-900">
        Personal Information
      </h3>
    </div>
    <div class="space-y-6 sm:mt-5">
      <x-inputs.group label="First Name" for="first_name">
        <x-inputs.text for="first_name" :value="$data['first_name']" />
      </x-inputs.group>
      <x-inputs.group label="Last Name" for="last_name">
        <x-inputs.text for="last_name" :value="$data['last_name']" />
      </x-inputs.group>
      <x-inputs.group label="Email address" for="email">
        <x-inputs.text for="email" :value="$data['email']" />
      </x-inputs.group>
      <x-inputs.group label="Street address" for="street_address">
        <x-inputs.text for="street_address" />
      </x-inputs.group>
      <x-inputs.group label="City" for="city">
        <x-inputs.text for="city" />
      </x-inputs.group>
      <x-inputs.group label="State" for="state">
        <x-inputs.text for="state" />
      </x-inputs.group>
      <x-inputs.group label="Zip" for="zip">
        <x-inputs.text for="zip" />
      </x-inputs.group>
    </div>
  </div>
  <div class="mt-8 border-t border-gray-200 pt-5">
    <div class="flex justify-end">
      <span class="ml-3 inline-flex rounded-md shadow-sm">
        <button type="submit"
          class="inline-flex justify-center py-2 px-4 border border-transparent text-sm leading-5 font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-500 focus:outline-none focus:border-indigo-700 focus:shadow-outline-indigo active:bg-indigo-700 transition duration-150 ease-in-out">
          Save
        </button>
      </span>
    </div>
  </div>
</form>
@endsection
```

C:\xampp8\htdocs\testauth\resources\views\components\inputs\group.blade.php

```php
@props(['label', 'for'])
<div class="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-start sm:border-t sm:border-gray-200 sm:pt-5">
  <label for="{{ $for }}" class="block text-sm font-medium leading-5 text-gray-700 sm:mt-px sm:pt-2">
    {{ $label }}
  </label>
  <div class="mt-1 sm:mt-0 sm:col-span-2">
    {{ $slot }}
  </div>
</div>
```

C:\xampp8\htdocs\testauth\resources\views\components\inputs\text.blade.php

```php
@props([
'for',
'type' => 'text',
'value' => ''
])
<div class="rounded-md shadow-sm">
  <input id="{{ $for }}" type="{{ $type }}" value="{{ $value }}" {{ $attributes->merge(['class' => 'bg-white border border-gray-200 py-2 px-3 rounded-lg w-full block w-full transition duration-150 ease-in-out sm:text-sm sm:leading-5']) }}
  />
</div>
```

### 5.4 [Passing Data To Components](https://laravel.com/docs/9.x/blade#passing-data-to-components)

<figure><img src="/files/NYrRwgHvIFwNbVLYVgKL" alt=""><figcaption></figcaption></figure>

C:\xampp8\htdocs\lva\app\View\Components\Alert.php

```php
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Alert extends Component
{
  public $type;
  public $message;
  public function __construct($type, $message)
  {
    $this->type = $type;
    $this->message = $message;
  }
  /**
   * Get the view / contents that represent the component.
   *
   * @return \Illuminate\Contracts\View\View|\Closure|string
   */
  public function render()
  {
    return view('components.alert');
  }
}

```

C:\xampp8\htdocs\lva\resources\views\welcome.blade.php

```
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Laravel</title>
</head>
<body class="antialiased">
  @php
    $message = "Messsss";
  @endphp
  <x-alert type="error" :message="$message" />
</body>
</html>

```

C:\xampp8\htdocs\lva\resources\views\components\alert.blade.php

```
<div class="alert alert-{{ $type }}">
  {{ $message }}
</div>

```

### 6.1. Áp dụng&#x20;

<figure><img src="/files/UdjSK9Z1eK7SE691q40T" alt=""><figcaption></figcaption></figure>

C:\xampp8\htdocs\testauth\resources\views\layouts\main.blade.php

```
<!DOCTYPE html>
<html lang="en">
<head>
  @include('inner.head')
  @yield('style')
</head>
<body>
  @include('layouts.sidebar')
  <div class="wrapper d-flex flex-column min-vh-100 bg-light">
    @include('layouts.header')
    <div class="body flex-grow-1 px-3">
      <div class="container-lg">
        @yield('main')
      </div>
    </div>
    @include('layouts.footer')
  </div>
  @include('inner.script')
  @yield('script')
</body>
</html>
```

C:\xampp8\htdocs\testauth\resources\views\banner\index.blade.php

```
@extends('layouts.main')
@section('main')
<div class="tab-content rounded-bottom">
  <div class="tab-pane p-3 active preview" role="tabpanel" id="preview-91">
    <table class="table table-bordered text-center">
      @php
        $width = ["","15%",""];
        $colspan = ["","",2];
        $label = ["ID","表示順","登録内容"];
      @endphp
      <x-tables.th :count="3" :width=$width :colspan=$colspan :label=$label></x-tables.th>
      <x-tables.td :data=$data></x-tables.td>
    </table>
  </div>
</div>
@endsection

```

C:\xampp8\htdocs\testauth\resources\views\components\tables\th.blade.php

```
<thead class="table-dark">
  <tr>
    @for ($i = 0; $i < $count; $i++)
      <th scope="col" width="{{ $width[$i] }}" colspan="{{ $colspan[$i] }}">{{ $label[$i] }}</th>
    @endfor
  </tr>
</thead>

```

C:\xampp8\htdocs\testauth\resources\views\components\tables\td.blade.php

```
<tbody>
  @foreach ($data as $dta)
  <tr>
    @foreach ($dta as $dt)
      <td scope="row">{{ $dt }}</td>
    @endforeach
  </tr>
  @endforeach
</tbody>
```

C:\xampp8\htdocs\testauth\app\Http\Controllers\BannerController.php

```php
public function index()
{
  $data = [
    [
      1,
      "Mark 1",
      "Otto 1",
      "@mdo 1"
    ],
    [
      2,
      "Mark 2",
      "Otto 2",
      "@mdo 2"
    ]
  ];
  return view('banner.index')->with(compact('data'));
}
```

#### Blade Components for your Layout

In the [latest blog post](https://beyondco.de/blog/using-laravel-view-components) I showed you how Laravels Blade view components work and how you can make use of them. In this part of the series, I want to focus on how we can use these components throughout our application - starting with the very basic: your layout.

In a typical Laravel application, you might have a file called `layouts/app.blade.php` that all of your other views extend from.

Such a view could look like this:

```html
<!DOCTYPE html>
<html>
    <head>
	    @yield('scripts')
    </head>
    <body>
	    @yield('content')
    </body>
</html>
```

And in your actual pages, you will `extend` that view and provide your content within the `content` section. Here's an example `welcome.blade.php` file:

```html
@extends('layouts.app')

@section('scripts')
	<!-- Some JS and styles -->
@endsection

@section('content')
  <div>My Page content is here</div>
@endsection
```

So far so good, so let's see how we can make use of our newly learned Blade components to refactor this.

First of all, we are going to create a new component called "Layout":

```
php artisan make:component Layout
```

Next, we can take all of our existing layout view code and place it inside of our new layout component view:

```html
<!-- /views/components/layout.blade.php -->
<!DOCTYPE html>
<html>
    <head>
	    @yield('scripts')
    </head>
    <body>
	    @yield('content')
    </body>
</html>
```

To make this work, the only thing we need to do in our `welcome.blade.php` file is, instead of extending our layout - we can just wrap all of the content inside of our new layout component, like this:

```html
<x-layout>
	@section('scripts')
		<!-- Some JS and styles -->
	@endsection
	
	@section('content')
	  <div>My Page content is here</div>
	@endsection
</x-layout>
```

This is already pretty good, but as we have seen in the previous post, Laravel provides a `$slot` variable that automatically holds all of the content that was placed inside of the blade component tags. So lets go and change our layout to make use of the `$slot` variable, instead of yielding a content section:

```html
<!-- /views/components/layout.blade.php -->
<!DOCTYPE html>
<html>
    <head>
	    @yield('scripts')
    </head>
    <body>
		  {{ $slot }}
    </body>
</html>
```

Instead of using the `@section` directive, we can now simply pass the data as is:

```html
<x-layout>
	@section('scripts')
		<!-- Some JS and styles -->
	@endsection
	
  <div>My Page content is here</div>
</x-layout>
```

Alright - so we got rid of the content section and wrapped everything into our layout component. That's already pretty cool and I think this improves the readability of our view component. Because of the indentation it is immediately clear which layout is being used. This `scripts` section is still bothering me though. So let's see how we can get rid of this as well - and there are multiple options.

### Named Slots

The first option that we have is to make use of a "named slot". We already discussed the `$slot` variable, that will automatically be populated with everything within the component HTML, but we can also manually specify a slot name. This can be done using the `x-slot` tag - which itself is sort of a pre-defined Blade component that comes out of the box with Laravel.

By passing a `name` property to our `x-slot`, we can make the data available within a variable with the same name as our `name` attribute.

Let's modify our layout component to make use of a new `$scripts` variable:

```html
<!-- /views/components/layout.blade.php -->
<!DOCTYPE html>
<html>
    <head>
	    {{ $scripts }}
    </head>
    <body>
		  {{ $slot }}
    </body>
</html>
```

To pass this variable to our view, we can now pass it into a `scripts` slot:

```html
<x-layout>
  <x-slot name="scripts">
		<!-- Some JS and styles -->
  </x-slot>
	
  <div>My Page content is here</div>
</x-layout>
```

Refresh the page, and you can see that everything works as expected. With this, we introduced an error though, as our `$scripts` variable is now mandatory within our layout - so if a view would not provide a `scripts` slot, you would get an error "Undefined variable: scripts".

While this works with a named slot, we no longer have the ability to append to the scripts section from within multiple of our views/components - because we don't have a real "section" anymore.

So what if we want to get rid of the `@section` directives and use a component for this instead? First of, lets get our `@yield` directive back into our layout component:

```html
<!DOCTYPE html>
<html>
    <head>
	    @yield('scripts')
    </head>
    <body>
		  {{ $slot }}
    </body>
</html>
```

Alright - now lets see how we can make use of this section, without using a directive.

### Renderless Blade components

When you create a custom Blade component, the class has a `render` method, that by default returns a string containing the name of the view for the given component:

```php
namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    public function render()
    {
        return view('components.alert');
    }
}
```

There's another way of returning a view though, which is by returning a callable, that is then going to return the actual view. In this case, our component only holds the data/state that was provided for the component, but it doesn't actually return a view - which is great for our section use case.

So lets create a new view component called `Section`:

```
php artisan make:component Section
```

Now instead of returning a view, we are actually going to return a function - that will return the `@section` directive for us:

```php
namespace App\View\Components;

use Illuminate\View\Component;

class Section extends Component
{
    public function render()
    {
        return function ($componentData) {
            return <<<BLADE
                @section("{$componentData['attributes']->get('name')}")
                    {$componentData['slot']}
                @endsection
            BLADE;
        };
    }
}
```

Alright - so lets break this render method down line by line.

The `render` method returns a callable with one parameter - an array holding the component data. This array has the following data and keys available:

* `componentName` - The name for the component, in our case "section"
* `attributes` - The `Illuminate\View\ComponentAttributeBag` instance that holds all of our component attributes
* `slot` - A `Illuminate\Support\HtmlString` object with the string that was passed to the default slot

Inside of this callable, we are returning a string - this string is escaped using PHPs [Heredoc Syntax](https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc).

Inside of this string, we can now return any Blade code that we want - so in our case, we are opening a `@section` directive, with the `name` attribute that was provided in the `<x-section` tag. Inside of that `@section` directive, we pass the slot of our component (and cast it to a string, as it's a HtmlString object). And last but not least, we close the section directive.

To make use of this renderless component, we can now rewrite our page view like this:

```html
<x-layout>
  <x-section name="scripts">
	 <!-- Some JS and styles -->
  </x-section>
	
  <div>My Page content is here</div>
</x-layout>
```

Yay - we did it! We got rid of our ugly directive and have successfully refactored it to make use of a custom blade component.

Is this better than using the directives? You'll have to decide for yourself - but I hope that this inspired you to take a look at renderless Blade components, as well as how you can use components for your traditional layout extensions.
