V2がリリースされました。🎉
技術的なアップグレードについて説明する前に、皆さんはこれらの変更の背後にある哲学的な基盤に興味があるかもしれませんね。
- Livewireは宣言型です。
フロントエンドと対話するための無限のユーティリティを提供するのではなく、Livewireは、フロントエンドとの相互操作をあなたの状態の「副作用」(つまりコンポーネントのプロパティ)にすることを目指しています。たとえば、新しい
$queryString
APIでは、バックエンドからブラウザのクエリ文字列を手動で更新するメソッドを提供するのではなく、フロントエンドのクエリ文字列に反映させたいコンポーネントプロパティを$queryString
プロパティで宣言します。 - Livewireは反定形コードです。
開発者がEloquentモデルをプロパティとして設定し、それらに直接
wire:model
(バインド)できるようにすることで、非常に多くの定形コードを省略できます。定形コードをさらに削除するために、V2では、コンポーネントパラメータは名前を照合し、パブリックプロパティに自動的に割り当てられるようにしました。今回、mount()
メソッドは、単にパラメータをプロパティに転送するためだけに使用するのでなく、使用しなければならないものにのみ使用します。雑音を消しましょう。 - Livewireはコアとなるバックエンドインターフェイスです。
wire:click
関係は、インターフェースを使いやすくする単なるシュガーシンタックスです。$wire
を追加することで、根底にあるパワーが明らかになります。Livewireを使用すると、axios.post()や、RESTfullエンドポイント、コントローラーなどの命令型/定形パターンを必要とせずに、バックエンドコードと直接かつ宣言的にインターフェイスを取れます。 - Livewireは使いやすい。
私が持っているすべての哲学の中で、私はこれをもっとも強く持っています。Livewireは常に途方もなく使いやすいものでなければなりません。私の目標はAPIを簡単に覚えて、ほとんどを推測できるようにすることです。機能を導入する前にLaravelの既存のパターンやAPIを徹底的に調べ、Livewireがその共有された知識を新規採用者のために活用できるかどうかを確認します。小さな一例は新しい
$rules
プロパティがあります。どんな名前も付けることができましたが、なぜ$rules
(LaravelのRequestオブジェクトによって設定された前例)以外の名前を付けるのでしょうか? APIが簡単で、直感的で、明確であると思わない場合、私は機能の導入を待ち、明確で美しいものが現れるまで煮詰めます。(少なくともこれが私の目標です。)
Composerのバージョンを更新する
composer.json
ファイルのlivewire/livewire
依存指定を^2.0
に更新しますcomposer update livewire/livewire
を実行しますphp artisan view:clear
を実行しますphp artisan livewire:publish --assets
を実行します(以前にアセットをリソース公開していた場合)
Alpinのバージョンを更新する
Livewire V2でAlpineJSを使用している場合は、バージョン2.7.0
以降を使用していることを確認してください。
例:
<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js" defer></script>
アプリケーションのコードを更新する
重大な変更とそのアップグレード手順を影響順に示します。
- 更新:
$updatesQueryString
から$queryString
- 削除: Route::livewire()
- 削除: Turbolinksサポート
- 変更:
assertSet()
- 削除: Propertyキャスタ
- 更新: Paginationビュー
- 更新: JavaScriptフック
- 更新: VueJsサポート
更新:$updatesQueryString
から$queryString
Livewire 1.xには、プロパティ値に基づいてブラウザのクエリ文字列を操作するためのより原始的なユーティリティがありました。V2には、クエリ文字列を操作するためのはるかに高度なユーティリティがあります。
最初の重大な変更は、$updatesQueryString
が$queryString
に変更されたことです。
class Search extends Component
{
// 以前
protected $updatesQueryString = ['search']
// 現在
protected $queryString = ['search']
}
新しいプロパティ名の他に、内部の仕組みに2つの重要な変更があります。
- プロパティ値は、ページの読み込み時にクエリ文字列から自動的に初期値に設定されるようになりました
- クエリ文字列システムは、
history.replaceState
の代わりに、ブラウザのhistory.pushState
APIを使用するようになりました(つまり、ブラウザの[戻る]ボタンをクリックして、古いクエリ文字列の変更に再度アクセスできます)。
クエリ文字列システムが自動的に初期値を設定するようになったため、mount()
メソッドでそれを行う必要はなくなりました。
class Search extends Component
{
...
public function mount()
{
// このようなコードはもう必要ありません。
// これで、searchプロパティが自動的に設定されます。
$this->search = request()->query('search', '');
}
}
削除:Route::livewire()
Livewire
1.xでは、Route::livewire()
メソッドを使用して、ページ全体のルートにコンポーネントを登録できました。
Livewire
2.0では、標準のRoute::get()
メソッドと完全修飾名前空間を使用して、Livewireコンポーネントをルートに直接渡すことができるようになりました。
// 以前
Route::livewire('/post', 'show-posts');
// 現在
Route::get('/post', \App\Http\Livewire\ShowPosts::class);
最初に注意することは、Laravel7を使用している場合は、app/Providers/RouteServiceProvider.php
からnamespace(...)
行を削除する必要があるということです。
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace) // Remove me
->group(base_path('routes/web.php'));
}
これはLaravel8でデフォルトで実行されますが、Laravel7を使用している場合はLivewireクラスをRoute::get()
に渡すことができるように、これを削除する必要があります。それ以外の場合、LaravelはRoute::get()
に渡されるすべてのクラスに名前空間を付加します。
1.xのLivewireはデフォルトで、resources/layouts/app.blade.php
にある従来のBladeレイアウトを使用してページレベルのコンポーネントをレンダリングします。2.0のLivewireはデフォルトと同じレイアウトファイルを使用しますが、レイアウトで新しいBladeコンポーネントの$slot
構文を使用していることを前提としています。例をご覧ください。
<!-- 以前 -->
<html>
<body>
@yield('content')
@livewireScripts
</body>
</html>
<!-- 現在 -->
<html>
<body>
{{ $slot }}
@livewireScripts
</body>
</html>
ルートファイルでルートのレイアウトを手動で設定していた場合、->layout()
メソッドは
->extends()
と呼ばれる新しいメソッドに移動され、render関数内に配置します。
// 以前
Route::livewire('/post', ShowPosts::class)
->layout('layouts.base')
->section('body');
// 現在
class ShowPosts extends Component
{
public function render()
{
return view('livewire.show-posts')
->extends('layouts.base')
->section('body');
}
}
手動で構成したレイアウトを新しい$slot
構文に更新する場合は、新しい->layout()
メソッドを使用して指定できます。このメソッドはデフォルトで$slot
を使用しますが、->slot()
メソッドを使用して名前付きスロットにレンダーするようにコンポーネントを設定することもできます。
class ShowPosts extends Component
{
public function render()
{
return view('livewire.show-posts')
->layout('layouts.base')
->slot('body');
}
}
削除:Turbolinksサポート
Livewireは、Turbolinksをはじめからサポートしなくなりました。
LivewireアプリケーションでTurbolinksを引き続き使用する場合は、LivewireのJavaScriptアセットと一緒にTurbolinksアダプターを含める必要があります。
...
@livewireScripts
<script src="https://cdn.jsdelivr.net/gh/livewire/[email protected]/dist/livewire-turbolinks.js" data-turbolinks-eval="false"></script>
</body>
このアダプターは新しいため、Turbolinks機能に関連する問題が発生する可能性があります。その場合は、アダプターのリポジトリへ問題を報告してください。
変更:assertSet()
Livewire
V1では、テストメソッドassertSet('property', 'value')
は、実際のLivewireコンポーネントのPHPインスタンスのプロパティの値に対してアサートするのではなく、JavaScriptで安全なLivewireペイロードのデータに対してテストしていました。これにより、assertSet()
から計算プロパティをテストすることが不可能でした。
V2では、assertSet())
が期待どおりに動作するようになりました。実際のPHPインスタンスのデータに対してアサーションを作成し、ペイロードデータに対してアサーションを行う場合は、新しいassertPayloadSet()
を使用できるようになりました。
ほとんどの人にとって、これはなにも変えることはありません。ただし、アップグレード中にテストスイートでassertSet()
の周辺でエラーが発生した場合は、テストをリファクタリングするか、assertPayloadSet()
を使用する必要があります。
削除:Propertyキャスタ
プロパティキャスターはLivewireV2で削除されました。この決定には3つの理由があります。
- 人々は主に、
Collection
とDateTime
のインスタンスであるプロパティにこれらを使用しました。これらは、はじめから自動的にキャストされるようになりました - そもそもこの機能を使用している(または認識している)ユーザーは多くありません。
- これとまったく同じ機能を実現する方法は他にもあります
次に例をいくつか示します。
// 以前
public $foo;
protected $casts = ['foo' => 'collection'];
public function mount()
{
$this->foo = collect(['foo', 'bar']);
}
// 現在
// (Collectionsは自動的にキャストされるようになりました)
public $foo;
public function mount()
{
$this->foo = collect(['foo', 'bar']);
}
// 以前
class AllCaps implements Castable {
public function cast($value)
{
return strtoupper($value);
}
public function uncast($value)
{
return strtolower($value);
}
}
class SomeComponent extends Component
{
public $foo;
protected $casts = ['foo' => AllCaps::class];
....
}
// 現在
class SomeComponent extends Component
{
public $foo;
public function hydrateFoo($value)
{
$this->foo = strtoupper($value);
}
public function dehydrateFoo($value)
{
$this->foo = strtolower($value);
}
....
}
更新:Paginationビュー
コンポーネントにWithPagination
を追加して結果をペジネーションし、$posts->links()
を使用してデフォルトのLivewireページ付けリンクビューに依存している場合、ビューはBootstrap-4からTailwindに更新されます。
Livewire
V2は引き続きBootstrap-4ページネーションをサポートしていますが、コンポーネントの$paginationTheme
プロパティを使用して設定する必要があります。
class ShowPosts extends Component
{
use WithPagination;
protected $paginationTheme = 'bootstrap';
...
}
V2は引き続きBootstrap-4をサポートしていますが、ペジネーションビューはLaravel8に一致するように更新されています。したがって、以前にV1で使用されていたビューとは少し異なります。V1のビューをまったく同じに使用するには:
- GitHubからビューソースをコピーします。
- 適切と思われる場所に新しいBladeファイルをペーストします。たとえば、
resources/views/pagination-links.blade.php
です。 - 次に、
->links()
メソッドに渡して、Bladeビューの中で参照します。
{{ $posts->links('pagination-links') }}
更新:JavaScriptフック
V2はV1と同じJavaScriptフックを提供しますが、3つの異なる変更があります。
- 名前を変更しました。
- パラメータの順序を変更し、一貫性を向上させました。
- "DomElement"ラッパーのインスタンスが渡されていた場所で、ネイティブDOM要素が渡されるようになりました。
比較のためにフックの使用法を並べて示します。
V1の名前 | V2の名前と使い方 |
---|---|
livewire.hook('componentInitialized', (component) => {}) |
Livewire.hook('component.initialized', (component) => {}) |
livewire.hook('elementInitialized', (el, component) => {}) |
Livewire.hook('element.initialized', (el, component) => {}) |
livewire.hook('beforeElementUpdate', (from, to, component) => {}) |
Livewire.hook('element.updating', (fromEl, toEl, component) => {}) |
livewire.hook('afterElementUpdate', (node, component) => {}) |
Livewire.hook('element.updated', (el, component) => {}) |
livewire.hook('elementRemoved', (el, component) => {}) |
Livewire.hook('element.removed', (el, component) => {}) |
livewire.hook('messageSent', (component, message) => {}) |
Livewire.hook('message.sent', (message, component) => {}) |
livewire.hook('messageFailed', (component) => {}) |
Livewire.hook('message.failed', (message, component) => {}) |
livewire.hook('responseReceived', (component, response) => {}) |
Livewire.hook('message.received', (message, component) => {}) |
livewire.hook('afterDomUpdate', (component) => {}) |
Livewire.hook('message.processed', (message, component) => {}) |
livewire.hook('beforeDomUpdate', (component) => {}) |
Livewire.hook('message.received', (message, component) => {}) |
注:いくつかのインスタンスでは、response
オブジェクトの代わりにmessage
オブジェクトが渡されるようになりました。response
はmessage
のプロパティとしてアクセスできます。(message.response
)
更新:VueJSサポート
みなさんのLivewireが現在、vue-pluginに依存している場合は、バージョン
0.2.x
から0.3.x
にアップグレードする必要があります。
...
@livewireScripts
// 以前
<script src="https://cdn.jsdelivr.net/gh/livewire/[email protected]/dist/livewire-vue.js"></script>
// 現在
<script src="https://cdn.jsdelivr.net/gh/livewire/[email protected]/dist/livewire-vue.js"></script>
</body>
サインオフ
このアップグレードが、あなたにさほど大きく影響しないことを祈ってます。
このドキュメントに質問や修正を加える場合は、GitHubのリポジトリでIssueを送信してください。
いつも、あなたのサポートとLivewireを使ってくれることに感謝しています!
Caleb