深く掘り下げたスクリーンキャストがある、Livewireに驚いてください。観る(英語版)
インラインコンポーネント
ページ上にLivewireコンポーネントをレンダーする最も基本的な方法は、<livewire:
タグ構文を使用することです。
<div>
<livewire:show-posts />
</div>
もしくは、@livewire
Bladeディレクティブを使用することもできます。
@livewire('show-posts')
独自の名前空間を持つサブフォルダー内にコンポーネントがある場合は、名前空間のプレフィックスとしてドット(.
)を使用する必要があります。
たとえば、app/Http/Livewire/Nav
フォルダ内にShowPosts
コンポーネントがある場合は、以下のように指定します。
<livewire:nav.show-posts />
パラメータ
パラメータの指定
<livewire:
タグに追加のパラメータを指定することで、データをコンポーネントに渡せます。
たとえば、show-post
コンポーネントがあるとします。$post
モデルを渡す方法は次のとおりです。
<livewire:show-post :post="$post">
もしくは、以下のようにBladeディレクティブを使用してパラメーターを渡します。
@livewire('show-post', ['post' => $post])
パラメータの受け取り
Livewireはパラメータを一致するパブリックなプロパティへ自動的に割り当てます。
たとえば、<livewire:show-post :post="$post">
の場合、show-post
コンポーネントに$post
という名前のパブリックプロパティがあれば、自動的に割り付けます。
class ShowPost extends Component
{
public $post;
...
}
何らかの理由でこの自動動作がうまく機能しない場合は、mount()
メソッドを使用し、パラメータをインターセプトできます。
class ShowPost extends Component
{
public $title;
public $content;
public function mount($post)
{
$this->title = $post->title;
$this->content = $post->content;
}
...
}
Tip!! 皆さんおなじみのクラスコンストラクター
__construct()
の代わりに、Livewireコンポーネントではmount()
を使用します。
コントローラーと同様に、タイプヒントのパラメーターを前に追加することにより、依存関係を注入できます。
use \Illuminate\Session\SessionManager;
class ShowPost extends Component
{
public $title;
public $content;
public function mount(SessionManager $session, $post)
{
$session->put("post.{$post->id}.last_viewed", now());
$this->title = $post->title;
$this->content = $post->content;
}
...
}
フルページコンポーネント
ページのメインコンテンツがLivewireコンポーネントである場合、コントローラーであるかのようにコンポーネントをLaravelのルートへ直接渡せます。
Route::get('/post', ShowPosts::class);
デフォルト動作としてLivewireは、ShowPosts
コンポーネントをresources/views/layouts/app.blade.php
にあるBladeレイアウトコンポーネントの{{ $slot }}
へレンダーします。
<head>
@livewireStyles
</head>
<body>
{{ $slot }}
@livewireScripts
</body>
Laravelコンポーネントの詳細は、Laravelのドキュメント(日本語訳)を参照してください。
レイアウトコンポーネントの設定
デフォルトとは異なるレイアウトファイルを指定する場合は、render()
から返すビューインスタンス上で、->layout()
メソッドを使用します。
class ShowPosts extends Component
{
...
public function render()
{
return view('livewire.show-posts')
->layout('layouts.base');
}
}
コンポーネントでデフォルト以外のスロットを使用している場合は、->slot()
をチェーンすることもできます。
public function render()
{
return view('livewire.show-posts')
->layout('layouts.base')
->slot('main');
}
他にもLivewireは、@extends
を使用した従来のBladeレイアウトファイルの使用をサポートしています。
以下のレイアウトファイルがあるとします。
<head>
@livewireStyles
</head>
<body>
@yield('content')
@livewireScripts
</body>
これを参照するようにLivewireへ指定するには、->layout()
の代わりに->extends()
を使います。
public function render()
{
return view('livewire.show-posts')
->extends('layouts.app');
}
コンポーネントが使用する@section
を指定する必要がある場合は、->section()
メソッドを使用し、指定できます。
public function render()
{
return view('livewire.show-posts')
->extends('layouts.app')
->section('body');
}
コンポーネントからレイアウトにデータを渡す必要がある場合は、layoutメソッドでデータを渡せます。
public function render()
{
return view('livewire.show-posts')
->layout('layouts.base', ['title' => 'Show Posts'])
}
ルートパラメータ
多くの場合、コントローラーメソッド内のルートパラメーターにアクセスする必要があります。コントローラを使用しないため、Livewireはmount
メソッドを使用してこの動作を模倣します。例をご覧ください。
Route::get('/post/{id}', ShowPost::class);
class ShowPost extends Component
{
public $post;
public function mount($id)
{
$this->post = Post::find($id);
}
...
}
ご覧のとおり、Livewireコンポーネント中のmount
メソッドは、パラメーターに関する限りコントローラーメソッドのように機能します。/post/123
にアクセスすると、mount
メソッドに渡した$id
変数には値として123
が入ります。
ルートモデルの結合
ご期待のとおり、Livewireコンポーネントはルートモデルの結合などコントローラーが使用しているすべての機能を実装しています。一例をご覧ください。
Route::get('/post/{post}', ShowPost::class);
class ShowPost extends Component
{
public $post;
public function mount(Post $post)
{
$this->post = $post;
}
}
PHP7.4を使用している場合は、クラスプロパティをタイプヒントすることもでき、Livewireは自動的にルートモデルを結合します。以下のコンポーネントの$post
プロパティは、mount()
メソッドを必要とせず、自動的に挿入されます。
class ShowPost extends Component
{
public Post $post;
}
Renderメソッド
Livewireコンポーネントの render
メソッドは、ページの初回読み込み時、「ならびに」それ以降のコンポーネントの更新時に毎回呼び出されます。
Tip!! 単純なコンポーネントでは、
render
メソッドを自分で定義する必要はありません。基本のLivewireコンポーネントクラスには、動的なrender
メソッドが含まれています。
Bladeビューを返す
render()
メソッドはBladeビューを返すことが期待されているため、コントローラーメソッドの作成と比較できます。以下に例を紹介します。
Note: Bladeビューには、確実にルート要素を1つだけ入れてください。
class ShowPosts extends Component
{
public function render()
{
return view('livewire.show-posts', [
'posts' => Post::all(),
]);
}
}
<div>
@foreach ($posts as $post)
@include('includes.post', $post)
@endforeach
</div>
テンプレート文字列を返す
Bladeビューに加え、オプションとしてrender()
からBladeテンプレート文字列を返せます。
class DeletePost extends Component
{
public Post $post;
public function delete()
{
$this->post->delete();
}
public function render()
{
return <<<'blade'
<div>
<button wire:click="delete">Delete Post</button>
</div>
blade;
}
}
Tip!! 上記のようなインラインコンポーネントの場合、作成時に
--inline
フラグを使用する必要があります。ʻartisan make:livewire delete-post --inline`