今さらだけどLaravelのコンポーネントの整理

## はじめに
Laravelを使用し、画面をReact、Vueのようにコンポーネント対応ができるようになっているので、今一度整理しました。

1.レイアウトでのコンポーネントの使用($slotの使用)
2.1にコンポーネントの入れ込み
3.コントローラから画面のコンポーネントにデータセット


## 1.レイアウトでのコンポーネントの使用
`x-app-layout`コンポーネントを作成します。
このコンポーネントは、Bladeコンポーネントを作成し、テンプレートとして使用することで、アプリケーション全体のレイアウトを統一する目的で使用されます。

### `AppLayout` コンポーネントの作成

まず、`app-layout`コンポーネントを作成する必要があります。以下は、その手順です。

1. **コンポーネントファイルの作成**  
   `resources/views/components/app-layout.blade.php`に以下の内容を追加します。

```app-layout.blade.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Application</title>
</head>
<body>
    <header>
        {{ $header }}
    </header>
    
    <main>
        {{ $slot }}
    </main>
    
    <footer>
        {{ $footer }}
    </footer>
</body>
</html>
```

　2. **使用するBladeファイルの作成**  
   次に、このレイアウトコンポーネントを使用するBladeテンプレートを作成します。例えば、`resources/views/welcome.blade.php`に以下の内容を追加します。

```welcome.blade.html
<x-app-layout>
    <x-slot name="header">
        <h1 style="margin-left: 20px;">Welcome to My Application</h1>
    </x-slot>

    <p style="margin-left: 20px;">This is the content of the welcome page.</p>

    <x-slot name="footer">
        <p style="margin-left: 20px;">Custom Footer Content</p>
    </x-slot>
</x-app-layout>

```
これにより、`welcome.blade.php`で定義された`header`、`footer`、および主要コンテンツが`app-layout`コンポーネントの適切な場所に挿入されます。

`<x-slot>`ディレクティブを使用して、`$header`と`$footer`の内容を定義し、`$slot`には名前が指定されていないコンテンツ（ここでは`<p>`タグの内容）が自動的に挿入されます。




![スクリーンショット 2024-06-18 16.51.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/65fcc3ec-703b-4f59-214c-6ceb7f6c88f4.png)


### その他
Laravel 8以降では、コンポーネントは自動的に検出されますが、以前のバージョンを使用している場合は、コンポーネントを手動で登録する必要がありました。

`AppServiceProvider`で次のように登録していました。

```php
use Illuminate\Support\Facades\Blade;

public function boot()
{
    Blade::component('app-layout', App\View\Components\AppLayout::class);
}
```

これにより、`<x-app-layout>`として使用できるようになっていたとのことです。



## 2.コンポーネントの入れ込み
`php artisan make:component Alert`コマンドを使用してコンポーネントを作成することはよくあります。このコマンドは、Bladeコンポーネントを簡単に作成するためのものです。

以下は、`Alert`コンポーネントを作成する具体的な手順です。

### コンポーネントの作成

1. **コンポーネントの作成コマンドの実行**  
   ターミナルで以下のコマンドを実行します。

```bash
php artisan make:component Alert
```

このコマンドにより、以下の2つのファイルが作成されます：
- `app/View/Components/Alert.php` (コンポーネントクラス)
- `resources/views/components/alert.blade.php` (コンポーネントのビュー)

2. **コンポーネントクラスの編集**
   `app/View/Components/Alert.php`ファイルを編集して、必要なプロパティやメソッドを追加します。

```php
namespace App\View\Components;

use Illuminate\View\Component;

class Alert extends Component
{
    public $type;
    public $message;

    /**
     * Create a new component instance.
     *
     * @return void
     */
    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');
    }
}
```

3. **コンポーネントのビューの編集**  
   `resources/views/components/alert.blade.php`ファイルを編集して、コンポーネントのHTMLを定義します。

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

4. **コンポーネントの使用**
   作成したコンポーネントをBladeテンプレートで使用します。例えば、`resources/views/welcome.blade.php`ファイルで以下のように使用できます。

```welcome.blade.html
<x-app-layout>
    <x-slot name="header">
        <h1 style="margin: 20px;">Welcome to My Application</h1>
    </x-slot>

    <p style="margin: 20px;">This is the content of the welcome page.</p>

    <x-alert type="success" message="Operation successful!" />
    <x-alert type="error" message="There was an error." />

    <x-slot name="footer">
        <p style="margin: 20px;">Custom Footer Content</p>
    </x-slot>
</x-app-layout>

```

これにより、`Alert`コンポーネントが生成され、指定されたプロパティに応じた表示が行われます。

![スクリーンショット 2024-06-18 17.02.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/ec589abb-41c5-ffc2-fb55-53a38b96cb66.png)


## 3.コントローラから画面のコンポーネントにデータセット
バックエンドからBladeコンポーネントに変数を渡す例を記載します。
コントローラからビューに変数を渡し、その変数をBladeコンポーネントに渡す形で実現できます。

以下に、具体的な手順を示します。

### 1. コントローラで変数を渡す

まず、コントローラでビューに変数を渡します。

```php
// app/Http/Controllers/AlertController.php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AlertController extends Controller
{
    public function show()
    {
        $alertType = 'error'; // バックエンドからの変数
        $alertMessage = 'There was an error.';

        return view('welcome', compact('alertType', 'alertMessage'));
    }
}
```

### 2. Bladeビューでコンポーネントに変数を渡す

次に、ビューで渡された変数をコンポーネントに渡します。

```welcome.blade.html
<!-- resources/views/welcome.blade.php -->
<x-app-layout>
    <x-slot name="header">
        <h1 style="margin: 20px;">Welcome to My Application</h1>
    </x-slot>

    <p style="margin: 20px;">This is the content of the welcome page.</p>

    <x-alert :type="$alertType" :message="$alertMessage" />

    <x-slot name="footer">
        <p style="margin: 20px;">Custom Footer Content</p>
    </x-slot>
</x-app-layout>
```
`<x-alert :type="$alertType" :message="$alertMessage" />`の箇所です。

### 3. コンポーネントビューの定義

最後に、コンポーネントのビューを定義します。`@props`を使用してデフォルト値を設定することもできます。

```alert.blade.html
<!-- resources/views/components/alert.blade.php -->
@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>
```

![スクリーンショット 2024-06-18 17.10.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/27344575-7abc-d281-7de4-97781a258cef.png)


## 参考記事

https://blog.capilano-fw.com/?p=11824

https://reffect.co.jp/laravel/laravel-components