これは、Laravel 7.15.0 の環境でのコンポーネントの利用方法についてになります。
コンポーネントの切り出し方については、これといって正解はなくて、各アプリケーションによると思うので、こういう風に作りましょうという形ではなくて、こういったパターンでも作れますよ。という形で紹介していきます。
Laravelでは、Bladeのコンポーネントと、Vueのコンポーネントが利用できるのですが、結構似たような使い方ができるので、どちらを使うか迷うかと思うので、何回かに分けてざっと機能や使い方を紹介してみます。
今回は、Bladeのコンポーネントの基本的な使い方を紹介します。
実際にここをコンポーネントかする意味はあるのかは別にして、
コンテンツ一覧ページを例にコンポーネント化していきます。
まずは、コンポーネント前の状態です。
<?php
namespace App\Http\Controllers;
class Contents extends Controller
{
public function list()
{
$contents_list = \DB::table('contents')->paginate(10);
return view('contents.list',['contents_list' => $contents_list]);
}
}
<h1>コンテンツ一覧</h1>
{{ $contents_list->total() }}
<div class="card">
<table class="table">
@foreach ($contents_list as $contents)
<tr>
<td><a href="/contents/info/{{ $contents->id }}">{{ $contents->title }}</a></td>
<td>{{ $contents->create_time }}</td>
<td><a href="/contents/remove/{{ $contents->id }}" class="btn btn-danger">削除</a></td>
</tr>
@endforeach
</table>
</div>
{{ $contents_list->links() }}
まずは大きめに、ページタイトルを残して一覧テーブルを丸ごとコンポーネント化してみます。
下記のコマンドでコンポーネントに必要なクラスとbladeファイルが生成されます。
php artisan make:component ContentsList
下記の2ファイルが追加されたことが確認できるかと思います。
ContentListは、bladeファイルでは、contents-listとなります。
app/View/Components/ContentsList.php
resources/views/components/contents-list.blade.php
この後ページに作成したコンポーネントを追加するには、下記のようにするだけです。
<h1>コンテンツ一覧</h1>
<x-contents-list />
Bladeファイル名に x- を付与したタグを挿入する形です。
まだ、コンポーネントの中身が空なので、この状態だと何も表示されないのでBladeファイルに試しに追加してみます。
<div>コンテンツ一覧表です</div>
これで、ページにコンテンツが追加されていることが確認できるかと思います。
では、実際にコンテンツの一覧表を表示します。
まずは、ContentsList.phpを編集します。
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class ContentsList extends Component
{
public $contents_list;
public function __construct($contents_list)
{
$this->contents_list = $contents_list;
}
public function render()
{
return view('components.contents-list');
}
}
コンポーネントでは、クラスのパブリックプロパティがビューで利用可能になります。
また、コンポーネントへは、constructの引数を通して値を渡すことができます。
上記の例では、コンテンツ一覧のデータを、constructで受け取って、ビューで利用可能なように、
パブリックプロパティに渡しています。
次に、Bladeファイルを記述します。
{{ $contents_list->total() }}
<div class="card">
<table class="table">
@foreach ($contents_list as $contents)
<tr>
<td><a href="/contents/info/{{ $contents->id }}">{{ $contents->title }}</a></td>
<td>{{ $contents->create_time }}</td>
<td><a href="/contents/remove/{{ $contents->id }}" class="btn btn-danger">削除</a></td>
</tr>
@endforeach
</table>
</div>
{{ $contents_list->links() }}
内容は、元々のソースと同じです。
これでコンポーネント側の準備が整ったので、最後にページ側からコンポーネントを呼び出す際に、コンテンツ一覧のデータの受け渡しを追加します。
<h1>コンテンツ一覧</h1>
<x-contents-list :contents_list="$contents_list" />
これで、コンポーネントを利用して、コンテンツ一覧を表示できたかと思います。
ちなみに、文字列等を渡す場合は、: なしで渡します。
<h1>コンテンツ一覧</h1>
<x-contents-list :contents_list="$contents_list" description="コンテンツの一覧を表示しています" />
次は、コンテンツ一覧全体ではなく、行をコンポーネントしてみます。
コンポーネントの作成は同様に
$ php artisan make:component Rows
下記の2ファイルが生成されます。
app/View/Components/Rows.php
resources/views/components/rows.blade.php
コンポーネント側を準備します。まずはViewクラス
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class Rows extends Component
{
public $contents;
public function __construct($contents)
{
$this->contents = $contents;
}
public function render()
{
return view('components.rows');
}
}
前回と違って、今回はコンテンツ一覧全体ではなく、コンテンツ単体を受け渡しています。
次にBladeファイル側です。
<tr>
<td><a href="/contents/info/{{ $contents->id }}">{{ $contents->title }}</a></td>
<td>{{ $contents->create_time }}</td>
<td><a href="/contents/remove/{{ $contents->id }}" class="btn btn-danger">削除</a></td>
</tr>
1行分を記述しています。
最後に、ページ側からコンポーネントを呼び出します。
<h1>コンテンツ一覧</h1>
{{ $contents_list->total() }}
<div class="card">
<table class="table">
@foreach ($contents_list as $contents)
<x-rows :contents="$contents"/>
@endforeach
</table>
</div>
{{ $contents_list->links() }}
今回は、主に表示側の分割をコンポーネント側で行ってみました。
次回は、ロジックの分割をBladeのコンポーネントの機能を使って行ってみたいと思います。