Readouble

Livewire v3 アクション

アクション

Livewireのアクションとは、ボタンのクリックやフォームの送信など、フロントエンドの操作により起動可能なコンポーネントのメソッドのことです。これにより、開発者はブラウザから直接PHPメソッドを呼び出すという開発者体験を得られ、アプリケーションのフロントエンドとバックエンドを結びつけるお決まりのコードの作成に手間取らずに、アプリケーションのロジックへ集中できます。Livewire actions are methods on your component that can be triggered by frontend interactions like clicking a button or submitting a form. They provide the developer experience of being able to call a PHP method directly from the browser, allowing you to focus on the logic of your application without getting bogged down writing boilerplate code connecting your application's frontend and backend.

CreatePostコンポーネント上のsaveアクションを呼び出す、基本的な例を見てみましょう。Let's explore a basic example of calling a save action on a CreatePost component:

<?php

namespace App\Livewire;

use Livewire\Component;
use App\Models\Post;

class CreatePost extends Component
{
    public $title = '';

    public $content = '';

    public function save()
    {
        Post::create([
            'title' => $this->title,
            'content' => $this->content,
        ]);

        return redirect()->to('/posts');
    }

    public function render()
    {
        return view('livewire.create-post');
    }
}
<form wire:submit="save"> <!-- [tl! highlight] -->
    <input type="text" wire:model="title">

    <textarea wire:model="content"></textarea>

    <button type="submit">Save</button>
</form>

上記の例では、ユーザーが"Save"をクリックしてフォームを送信すると、wire:submitsubmitイベントをインターセプトし、サーバ上のsave()アクションを呼び出します。In the above example, when a user submits the form by clicking "Save", wire:submit intercepts the submit event and calls the save() action on the server.

基本的に、アクションはAJAXリクエストを手作業で送信および処理する手間をかけずに、ユーザー操作をサーバ側の機能に簡単にマッピングする方法です。In essence, actions are a way to easily map user interactions to server-side functionality without the hassle of submitting and handling AJAX requests manually.

コンポーネントのリフレッシュRefreshing a component

コンポーネントの単純な「リフレッシュ」をトリガーしたい場合があるでしょう。たとえば、データベース内の何かのステータスを確認するコンポーネントがある場合、表示された結果をリフレッシュできるボタンをユーザーへ表示したい場合です。Sometimes you may want to trigger a simple "refresh" of your component. For example, if you have a component checking the status of something in the database, you may want to show a button to your users allowing them to refresh the displayed results.

これは、通常コンポーネントメソッドを参照できる場所ならどこでも、Livewireのシンプルな$refreshアクションを使用して実行可能です。You can do this using Livewire's simple $refresh action anywhere you would normally reference your own component method:

<button type="button" wire:click="$refresh">...</button>

$refreshアクションがトリガーされると、Livewireはサーバとのラウンドトリップを行い、メソッドを呼び出すことなくコンポーネントを再レンダリングします。When the $refresh action is triggered, Livewire will make a server-roundtrip and re-render your component without calling any methods.

コンポーネント内の保留中のデータ更新(たとえば、wire:model結合)は、コンポーネントがリフレッシュされるときにサーバへ適用されることに注意することが重要です。It's important to note that any pending data updates in your component (for example wire:model bindings) will be applied on the server when the component is refreshed.

内部的にLivewireは、Livewireコンポーネントがサーバ上で更新されるたび、"commit"という名前を使用します。この用語を使用したい場合、$refreshの代わりに$commitヘルパを使用できます。この2つは同じです。Internally, Livewire uses the name "commit" to refer to any time a Livewire component is updated on the server. If you prefer this terminology, you can use the $commit helper instead of $refresh. The two are identical.

<button type="button" wire:click="$commit">...</button>

LivewireコンポーネントでAlpineJSを使用して、コンポーネントのリフレッシュをトリガーすることもできます。You can also trigger a component refresh using AlpineJS in your Livewire component:

<button type="button" x-on:click="$wire.$refresh()">...</button>

詳細は、Livewire内でAlpineを使用するためのドキュメントをお読みください。Learn more by reading the documentation for using Alpine inside Livewire[/docs/alpine].

アクションの確認Confirming an action

データベースから投稿を削除するなど、ユーザーが危険なアクションを実行できるようにする場合、そのアクションを実行するかどうかを確認するために、確認アラートを表示したいでしょう。When allowing users to perform dangerous actions—such as deleting a post from the database—you may want to show them a confirmation alert to verify that they wish to perform that action.

Livewireは、wire:confirmというシンプルなディレクティブを提供しており、これを簡単にできます。Livewire makes this easy by providing a simple directive called wire:confirm:

<button
    type="button"
    wire:click="delete"
    wire:confirm="Are you sure you want to delete this post?"
>
    Delete post <!-- [tl! highlight:-2,1] -->
</button>

wire:confirmをLivewireアクションを含む要素へ追加すれば、ユーザーがそのアクションをトリガーしたとき、指定したメッセージを含む確認ダイアログを表示します。"OK"を押してアクションを確認するか、"cancel"を押すか、Escapeキーを押すかのどれかを行ってもらえますWhen wire:confirm is added to an element containing a Livewire action, when a user tries to trigger that action, they will be presented with a confirmation dialog containing the provided message. They can either press "OK" to confirm the action, or press "Cancel" or hit the escape key.

詳細は、wire:confirmドキュメントページを参照してください。For more information, visit the wire:confirm documentation page[/docs/wire-confirm].

イベントリスナEvent listeners

Livewireは、さまざまなユーザー操作に対応できるよう、さまざまなイベントリスナをサポートしています。Livewire supports a variety of event listeners, allowing you to respond to various types of user interactions:

リスナListener 説明Description
wire:clickwire:click 要素をクリックしたとき起動Triggered when an element is clicked
wire:submitwire:submit フォームを送信したとき起動Triggered when a form is submitted
wire:keydownwire:keydown キーを押したとき起動Triggered when a key is pressed down
wire:keyupwire:keyup キーを離したとき起動Triggered when a key is released
wire:mouseenterwire:mouseenter マウスが要素へ入ったとき起動Triggered when the mouse enters an element
wire:*wire:* wire:の後に続くテキストは、リスナのイベント名として使用Whatever text follows wire: will be used as the event name of the listener

wire:の後のイベント名は任意であるため、Livewireはリッスンする必要がある可能性のある任意のブラウザイベントをサポートします。たとえば、transitionendをリッスンするには、wire:transitionendを使用します。Because the event name after wire: can be anything, Livewire supports any browser event you might need to listen for. For example, to listen for transitionend, you can use wire:transitionend.

特定キーのリッスンListening for specific keys

Livewireの便利なエイリアスの1つを使用すると、キープレスイベントリスナを特定のキーまたはキーの組み合わせに絞り込めます。You can use one of Livewire's convenient aliases to narrow down key press event listeners to a specific key or combination of keys.

たとえば、ユーザーが検索ボックスに入力した後で Enterキーを押したときに検索を実行するには、wire:keydown.enterを使用できます。For example, to perform a search when a user hits Enter after typing into a search box, you can use wire:keydown.enter:

<input wire:model="query" wire:keydown.enter="searchPosts">

最初のキーエイリアスの後にさらにキーエイリアスをチェーンして、キーの組み合わせをリッスンできます。たとえば、Shiftキーが押されている間のみEnterキーをリッスンする場合は、次のように記述できます。You can chain more key aliases after the first to listen for combinations of keys. For example, if you would like to listen for the Enter key only while the Shift key is pressed, you may write the following:

<input wire:keydown.shift.enter="...">

以下に、使用可能なすべてのキー修飾子のリストを示します。Below is a list of all the available key modifiers:

修飾子Modifier キーKey
.shift.shift ShiftShift
.enter.enter EnterEnter
.space.space SpaceSpace
.ctrl.ctrl CtrlCtrl
.cmd.cmd CmdCmd
.meta.meta MacのCmd、WindowsのWindowsキーCmd on Mac, Windows key on Windows
.alt.alt AltAlt
.up.up 上矢印Up arrow
.down.down 下矢印Down arrow
.left.left 左矢印Left arrow
.right.right 右矢印Right arrow
.escape.escape EscapeEscape
.tab.tab TabTab
.caps-lock.caps-lock Caps LockCaps Lock
.equal.equal イコール、=Equal, =
.period.period ピリオド、.Period, .
.slash.slash スラッシュ、/Forward Slash, /

イベントハンドラ修飾子Event handler modifiers

Livewireは、一般的なイベント処理タスクを簡単にするための便利な修飾子も用意しています。Livewire also includes helpful modifiers to make common event-handling tasks trivial.

たとえば、イベントリスナ内からevent.preventDefault()を呼び出す必要がある場合は、イベント名の末尾に.preventを付けます。For example, if you need to call event.preventDefault() from inside an event listener, you can suffix the event name with .prevent:

<input wire:keydown.prevent="...">

以下に、使用可能なすべてのイベントリスナ修飾子とその機能の完全なリストを示します。Here is a full list of all the available event listener modifiers and their functions:

修飾子Modifier 機能Key
.prevent.prevent .preventDefault()の呼び出しと同等Equivalent of calling .preventDefault()
.stop.stop .stopPropagation()の呼び出しと同等Equivalent of calling .stopPropagation()
.window.window windowオブジェクトでイベントをリッスンListens for event on the window object
.outside.outside 要素の「外側(outside)」のクリックのみをリッスンOnly listens for clicks "outside" the element
.document.document documentオブジェクトでイベントをリッスンListens for events on the document object
.once.once リスナが1回だけ呼び出されるようにするEnsures the listener is only called once
.debounce.debounce ハンドラをデフォルト値の250msで間引くDebounce the handler by 250ms as a default
.debounce.100ms.debounce.100ms 指定時間でハンドラを間引くDebounce the handler for a specific amount of time
.throttle.throttle ハンドラが最低でも毎回250msごとに呼び出されるようスロットThrottle the handler to being called every 250ms at minimum
.throttle.100ms.throttle.100ms カスタム間隔でハンドラをスロットリングThrottle the handler at a custom duration
.self.self イベントがこの要素で発生した場合にのみリスナを呼び出し、子要素では呼び出さないOnly call listener if event originated on this element, not children
.camel.camel イベント名をキャメルケースへ変換 (wire:custom-event -> "customEvent")Converts event name to camel case (wire:custom-event -> "customEvent")
.dot.dot イベント名をドット表記へ変換(wire:custom-event -> "custom.event")Converts event name to dot notation (wire:custom-event -> "custom.event")
.passive.passive wire:touchstart.passiveはスクロールパフォーマンスをブロックしないwire:touchstart.passive won't block scroll performance
.capture.capture 「キャプチャ」フェーズでイベントをリッスンするListen for event in the "capturing" phase

wire:Alpinex-onディレクティブを内部で使用しているため、これらの修飾子はAlpineにより利用可能です。これらの修飾子をいつ使用する必要があるかの詳細は、Alpineのイベントドキュメントを参照してください。Because wire: uses Alpine's[https://alpinejs.dev] x-on directive under the hood, these modifiers are made available to you by Alpine. For more context on when you should use these modifiers, consult the Alpine Events documentation[https://alpinejs.dev/essentials/events].

サードパーティイベントの処理Handling third-party events

Livewireは、サードパーティライブラリによって発生した、カスタムイベントのリッスンもサポートしています。Livewire also supports listening for custom events fired by third-party libraries.

たとえば、プロジェクトでTrixリッチテキストエディターを使用しており、trix-changeイベントをリッスンしてエディターのコンテンツをキャプチャしたいとします。これは、wire:trix-changeディレクティブを使用して実現できます。For example, let's imagine you're using the Trix[https://trix-editor.org/] rich text editor in your project and you want to listen for the trix-change event to capture the editor's content. You can accomplish this using the wire:trix-change directive:

<form wire:submit="save">
    <!-- ... -->

    <trix-editor
        wire:trix-change="setPostContent($event.target.value)"
    ></trix-editor>

    <!-- ... -->
</form>

この例では、trix-changeイベントがトリガーされるたびにsetPostContentアクションを呼び出し、LivewireコンポーネントのcontentプロパティをTrixエディターの現在の値で更新します。In this example, the setPostContent action is called whenever the trix-change event is triggered, updating the content property in the Livewire component with the current value of the Trix editor.

lightbulb Info: $eventを使用してイベントオブジェクトへアクセスできます。 Livewireイベントハンドラ内では、$eventを使用してイベントオブジェクトにアクセスできます。これは、イベントに関する情報を参照するのに役立ちます。たとえば、$event.targetを使用して、イベントをトリガーした要素にアクセスできます。[!info] You can access the event object using $event Within Livewire event handlers, you can access the event object via $event. This is useful for referencing information on the event. For example, you can access the element that triggered the event via $event.target.

warning Warning! 上記のTrixデモコードは不完全であり、イベントリスナのデモンストレーションとしてのみ示しています。そのまま使用すると、すべてのキーストロークでネットワークリクエストが発生します。よりパフォーマンスの高い実装は次のようになります。[!warning] The Trix demo code above is incomplete and only useful as a demonstration of event listeners. If used verbatim, a network request would be fired on every single keystroke. A more performant implementation would be:

<trix-editor
   x-on:trix-change="$wire.content = $event.target.value"
></trix-editor>

ディスパッチしたカスタムイベントのリッスンListening for dispatched custom events

アプリケーションでAlpineからカスタムイベントをディスパッチする場合、Livewireを使用してそれらのイベントをリッスンすることもできます。If your application dispatches custom events from Alpine, you can also listen for those using Livewire:

<div wire:custom-event="...">

    <!-- このコンポーネント内で深くネストされている: -->
    <button x-on:click="$dispatch('custom-event')">...</button>

</div>

上記の例でボタンがクリックされると、custom-eventイベントをディスパッチし、wire:custom-eventがそれをキャッチし、特定のアクションを呼び出すLivewireコンポーネントのルートまでバブルアップします。When the button is clicked in the above example, the custom-event event is dispatched and bubbles up to the root of the Livewire component where wire:custom-event catches it and invokes a given action.

アプリケーションの他の場所でディスパッチしたイベントをリッスンする場合は、代わりにイベントがwindowオブジェクトまでバブルアップするのを待って、そこでリッスンする必要があります。幸いなことに、Livewireでは、任意のイベントリスナに単純な.window修飾子を追加し、これを簡単にできます。If you want to listen for an event dispatched somewhere else in your application, you will need to wait instead for the event to bubble up to the window object and listen for it there. Fortunately, Livewire makes this easy by allowing you to add a simple .window modifier to any event listener:

<div wire:custom-event.window="...">
    <!-- ... -->
</div>

<!-- コンポーネントの外部のページのどこかでディスパッチする -->
<button x-on:click="$dispatch('custom-event')">...</button>

フォームの送信中に入力を無効にするDisabling inputs while a form is being submitted

以前に説明した、CreatePostの例を考えてみましょう。Consider the CreatePost example we previously discussed:

<form wire:submit="save">
    <input wire:model="title">

    <textarea wire:model="content"></textarea>

    <button type="submit">Save</button>
</form>

ユーザーが"Save"をクリックすると、ネットワークリクエストをサーバへ送信し、Livewireコンポーネントでsave()アクションを呼び出します。When a user clicks "Save", a network request is sent to the server to call the save() action on the Livewire component.

ただし、ユーザーが低速なインターネット接続でこのフォームに入力しているとしましょう。ユーザーは"Save"をクリックしますが、ネットワークリクエストが通常よりも時間がかかるため、最初は何も起こりません。送信に失敗したのではないかと思い、最初のリクエストがまだ処理されている間に、もう一度"Save"ボタンをクリックしようとするかもしれません。But, let's imagine that a user is filling out this form on a slow internet connection. The user clicks "Save" and nothing happens initially because the network request takes longer than usual. They might wonder if the submission failed and attempt to click the "Save" button again while the first request is still being handled.

この場合、同じアクションに対して2つのリクエストが同時に処理されます。In this case, there would be two requests for the same action being processed at the same time.

このシナリオを防ぐために、Livewireは、wire:submitアクションが処理されている間、送信ボタンと<form>要素内のすべてのフォーム入力を自動的に無効にします。これにより、フォームが誤って2回送信されることがなくなります。To prevent this scenario, Livewire automatically disables the submit button and all form inputs inside the <form> element while a wire:submit action is being processed. This ensures that a form isn't accidentally submitted twice.

低速な接続を使用しているユーザーの混乱をさらに軽減するため、わずかな背景色の変更やSVGアニメーションなど、何らかのローディングインジケーターを表示すると役立つことがあります。To further lessen the confusion for users on slower connections, it is often helpful to show some loading indicator such as a subtle background color change or SVG animation.

Livewireはページのどこでも、ローディングインジケータを簡単に表示/非表示するwire:loadingディレクティブを提供しています。"Save"ボタンの下にローディングメッセージを表示するwire:loadingの簡単な使用例を以下に示します。Livewire provides a wire:loading directive that makes it trivial to show and hide loading indicators anywhere on a page. Here's a short example of using wire:loading to show a loading message below the "Save" button:

<form wire:submit="save">
    <textarea wire:model="content"></textarea>

    <button type="submit">Save</button>

    <span wire:loading>Saving...</span> <!-- [tl! highlight] -->
</form>

wire:loadingは、さまざまなより強力な機能を備えた強力な機能です。詳細は、ローディングドキュメント全体をご確認くださいwire:loading is a powerful feature with a variety of more powerful features. Check out the full loading documentation for more information[/docs/wire-loading].

パラメータの受け渡しPassing parameters

Livewireでは、Bladeテンプレートからコンポーネントのアクションへパラメータを渡すことができ、アクションを呼び出すときに、そのアクションへ追加のデータまたは状態をフロントエンドから提供する機会があります。Livewire allows you to pass parameters from your Blade template to the actions in your component, giving you the opportunity to provide an action additional data or state from the frontend when the action is called.

たとえば、ユーザーが投稿を削除できるShowPostsコンポーネントがあるとします。投稿のIDをパラメータとしてLivewireコンポーネントのdelete()アクションへ渡すことができます。次に、アクションは関連する投稿をフェッチし、データベースから削除できます。For example, let's imagine you have a ShowPosts component that allows users to delete a post. You can pass the post's ID as a parameter to the delete() action in your Livewire component. Then, the action can fetch the relevant post and delete it from the database:

<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use App\Models\Post;

class ShowPosts extends Component
{
    public function delete($id)
    {
        $post = Post::findOrFail($id);

        $this->authorize('delete', $post);

        $post->delete();
    }

    public function render()
    {
        return view('livewire.show-posts', [
            'posts' => Auth::user()->posts,
        ]);
    }
}
<div>
    @foreach ($posts as $post)
        <div wire:key="{{ $post->id }}">
            <h1>{{ $post->title }}</h1>
            <span>{{ $post->content }}</span>

            <button wire:click="delete({{ $post->id }})">Delete</button> <!-- [tl! highlight] -->
        </div>
    @endforeach
</div>

IDが2の投稿の場合、上記のBladeテンプレートの"Delete"ボタンは、ブラウザで次のようにレンダーされます。For a post with an ID of 2, the "Delete" button in the Blade template above will render in the browser as:

<button wire:click="delete(2)">Delete</button>

このボタンをクリックすると、delete()メソッドが呼び出され、$idへ"2"の値が渡されます。When this button is clicked, the delete() method will be called and $id will be passed in with a value of "2".

warning Warning! アクションパラメータを信用しないでください: アクションパラメータは、HTTPリクエストの入力と同様に扱う必要があります。つまり、アクションパラメータの値を信用してはなりません。データベースを更新する前に、エンティティの所有権を常に確認する必要があります。[!warning] Don't trust action parameters Action parameters should be treated just like HTTP request input, meaning action parameter values should not be trusted. You should always authorize ownership of an entity before updating it in the database.

詳しくは、セキュリティの考察事項とベストプラクティスに関するドキュメントをご覧ください。For more information, consult our documentation regarding security concerns and best practices[/docs/actions#security-concerns].

アクションにパラメータとして渡した対応するモデルIDにより、Eloquentモデルを自動的に解決する便利な方法があります。これは、ルートモデル結合と非常によく似ています。使い始めるには、アクションパラメータでモデルクラスを型ヒントしてください。適切なモデルをデータベースから自動的に取得し、IDの代わりにアクションへ渡します。As an added convenience, you may automatically resolve Eloquent models by a corresponding model ID that is provided to an action as a parameter. This is very similar to route model binding[/docs/components#using-route-model-binding]. To get started, type-hint an action parameter with a model class and the appropriate model will automatically be retrieved from the database and passed to the action instead of the ID:

<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use App\Models\Post;

class ShowPosts extends Component
{
    public function delete(Post $post) // [tl! highlight]
    {
        $this->authorize('delete', $post);

        $post->delete();
    }

    public function render()
    {
        return view('livewire.show-posts', [
            'posts' => Auth::user()->posts,
        ]);
    }
}

依存性注入Dependency injection

アクションのシグネチャでパラメータを型ヒントすることにより、Laravelの依存性注入システムを利用できます。LivewireとLaravelは、コンテナからアクションの依存関係を自動的に解決します。You can take advantage of Laravel's dependency injection[https://laravel.com/docs/controllers#dependency-injection-and-controllers] system by type-hinting parameters in your action's signature. Livewire and Laravel will automatically resolve the action's dependencies from the container:

<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use App\Repositories\PostRepository;

class ShowPosts extends Component
{
    public function delete(PostRepository $posts, $postId) // [tl! highlight]
    {
        $posts->deletePost($postId);
    }

    public function render()
    {
        return view('livewire.show-posts', [
            'posts' => Auth::user()->posts,
        ]);
    }
}
<div>
    @foreach ($posts as $post)
        <div wire:key="{{ $post->id }}">
            <h1>{{ $post->title }}</h1>
            <span>{{ $post->content }}</span>

            <button wire:click="delete({{ $post->id }})">Delete</button> <!-- [tl! highlight] -->
        </div>
    @endforeach
</div>

この例で、delete()メソッドは、渡された$postIdパラメータを受け取る前に、Laravelのサービスコンテナを介して依存解決したPostRepositoryインスタンスを受け取ります。In this example, the delete() method receives an instance of PostRepository resolved via Laravel's service container[https://laravel.com/docs/container#main-content] before receiving the provided $postId parameter.

Alpineからのアクション呼び出しCalling actions from Alpine

LivewireはAlpineとシームレスに統合しています。実際、内部的にすべてのLivewireコンポーネントは、Alpineコンポーネントでもあります。これは、コンポーネント内でAlpineを最大限に活用して、JavaScriptによるクライアント側のインタラクティブ性を追加できることを意味します。Livewire integrates seamlessly with Alpine[https://alpinejs.dev/]. In fact, under the hood, every Livewire component is also an Alpine component. This means you can take full advantage of Alpine within your components to add JavaScript powered client-side interactivity.

この組み合わせをさらに強力にするために、LivewireはPHPコンポーネントのJavaScript表現として扱えるマジック$wireオブジェクトをAlpineに公開しています。$wireを介してパブリックプロパティにアクセスおよび変更することに加え、アクションを呼び出すこともできます。$wireオブジェクトでアクションが呼び出されると、対応するPHPメソッドをバックエンドのLivewireコンポーネントで呼び出します。To make this pairing even more powerful, Livewire exposes a magic $wire object to Alpine that can be treated as a JavaScript representation of your PHP component. In addition to accessing and mutating public properties via $wire[/docs/properties#accessing-properties-from-javascript], you can call actions. When an action is invoked on the $wire object, the corresponding PHP method will be invoked on your backend Livewire component:

<button x-on:click="$wire.save()">Save Post</button>

さらに、より複雑な例を示すと、Alpineのx-intersectユーティリティを使用し、特定の要素がページ上で表示可能(visible)になったときに、incrementViewCount() Livewireアクションを起動できます。Or, to illustrate a more complex example, you might use Alpine's x-intersect[https://alpinejs.dev/plugins/intersect] utility to trigger a incrementViewCount() Livewire action when a given element is visible on the page:

<div x-intersect="$wire.incrementViewCount()">...</div>

パラメータの受け渡しPassing parameters

$wireメソッドへ渡すパラメータはすべて、PHPクラスメソッドにも渡されます。たとえば、次のLivewireアクションを考えてみましょう。Any parameters you pass to the $wire method will also be passed to the PHP class method. For example, consider the following Livewire action:

public function addTodo($todo)
{
    $this->todos[] = $todo;
}

コンポーネントのBladeテンプレート内で、Alpineを介してこのアクションを呼び出し、アクションに渡されるパラメータを指定できます。Within your component's Blade template, you can invoke this action via Alpine, providing the parameter that should be given to the action:

<div x-data="{ todo: '' }">
    <input type="text" x-model="todo">

    <button x-on:click="$wire.addTodo(todo)">Add Todo</button>
</div>

ユーザーがテキスト入力に「ゴミを捨てる」と入力し、"Add Todo"ボタンを押した場合、addTodo()メソッドが起動されされ、$todoパラメータの値は「ゴミを捨てる」になります。If a user had typed in "Take out the trash" into the text input and the pressed the "Add Todo" button, the addTodo() method will be triggered with the $todo parameter value being "Take out the trash".

戻り値を受け取るReceiving return values

さらに強力な機能として、呼び出された$wireアクションは、ネットワークリクエストの処理中にpromiseを返します。サーバの応答を受信すると、promiseはバックエンドアクションが返した値で解決されます。For even more power, invoked $wire actions return a promise while the network request is processing. When the server response is received, the promise resolves with the value returned by the backend action.

たとえば、次のアクションを持つLivewireコンポーネントを考えてみましょう。For example, consider a Livewire component that has the following action:

use App\Models\Post;

public function getPostCount()
{
    return Post::count();
}

$wireを使用すると、アクションを呼び出し、返された値を解決できます。Using $wire, the action may be invoked and its returned value resolved:

<span x-init="$el.innerHTML = await $wire.getPostCount()"></span>

この例で、getPostCount()メソッドが"10"を返した場合、<span>タグの中身も"10"になります。In this example, if the getPostCount() method returns "10", the <span> tag will also contain "10".

Livewireを使用するとき、Alpineの知識は必須ではありません。しかし、これは非常に強力なツールであり、Alpineを知ることで、Livewireのエクスペリエンスと生産性が向上します。Alpine knowledge is not required when using Livewire; however, it's an extremely powerful tool and knowing Alpine will augment your Livewire experience and productivity.

JavaScriptアクションJavaScript actions

Livewireを使用すると、サーバリクエストを行わず、完全にクライアント側で実行されるJavaScriptアクションを定義できます。これは、以下の2シナリオで役立ちます。Livewire allows you to define JavaScript actions that run entirely on the client-side without making a server request. This is useful in two scenarios:

  1. サーバとの通信を必要としない単純なUI更新を実行する場合When you want to perform simple UI updates that don't require server communication
  2. サーバリクエストを行う前に、JavaScriptを使用してUIを楽観的に更新する場合When you want to optimistically update the UI with JavaScript before making a server request

JavaScriptアクションを定義するには、コンポーネントの<script>タグ内で$js()関数を使用します。To define a JavaScript action, you can use the $js() function inside a <script> tag in your component.

以下はサーバリクエストを行う前に、投稿をブックマークするため、JavaScriptアクションを使用してUIを楽観的に更新する例です。JavaScriptアクションは、即座に塗りつぶしたブックマークアイコンを表示し、それからリクエストを行い、そのブックマークをデータベースへ永続化します。Here's an example of bookmarking a post that uses a JavaScript action to optimistically update the UI before making a server request. The JavaScript action immediately shows the filled bookmark icon, then makes a request to persist the bookmark in the database:

<?php

namespace App\Livewire;

use Livewire\Component;
use App\Models\Post;

class ShowPost extends Component
{
    public Post $post;

    public $bookmarked = false;

    public function mount()
    {
        $this->bookmarked = $this->post->bookmarkedBy(auth()->user());
    }

    public function bookmarkPost()
    {
        $this->post->bookmark(auth()->user());

        $this->bookmarked = $this->post->bookmarkedBy(auth()->user());
    }

    public function render()
    {
        return view('livewire.show-post');
    }
}
<div>
    <button wire:click="$js.bookmark" class="flex items-center gap-1">
        {{-- 輪郭だけのブックマークアイコン --}}
        <svg wire:show="!bookmarked" wire:cloak xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-6">
            <path stroke-linecap="round" stroke-linejoin="round" d="M17.593 3.322c1.1.128 1.907 1.077 1.907 2.185V21L12 17.25 4.5 21V5.507c0-1.108.806-2.057 1.907-2.185a48.507 48.507 0 0 1 11.186 0Z" />
        </svg>

        {{-- 塗りつぶしたブックマークアイコン --}}
        <svg wire:show="bookmarked" wire:cloak xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-6">
            <path fill-rule="evenodd" d="M6.32 2.577a49.255 49.255 0 0 1 11.36 0c1.497.174 2.57 1.46 2.57 2.93V21a.75.75 0 0 1-1.085.67L12 18.089l-7.165 3.583A.75.75 0 0 1 3.75 21V5.507c0-1.47 1.073-2.756 2.57-2.93Z" clip-rule="evenodd" />
        </svg>
    </button>
</div>

@script
<script>
    $js('bookmark', () => {
        $wire.bookmarked = !$wire.bookmarked

        $wire.bookmarkPost()
    })
</script>
@endscript

ユーザーがハートボタンをクリックすると、以降のシーケンスが発生します。When a user clicks the heart button, the following sequence occurs:

  1. "bookmark" JavaScriptアクションを起動しますThe "bookmark" JavaScript action is triggered
  2. ハートアイコンは、クライアント側で$wire.bookmarkedを切り替えることで、すぐに更新されますThe heart icon immediately updates by toggling $wire.bookmarked on the client-side
  3. bookmarkPost()メソッドが呼び出され、変更がデータベースへ保存されますThe bookmarkPost() method is called to save the change to the database

これにより、ブックマークの状態が適切に保持されるのを保証しながら、即時に視覚的なフィードバックを提供しています。This provides instant visual feedback while ensuring the bookmark state is properly persisted.

Alpineからの呼び出しCalling from Alpine

$wireオブジェクトを使用し、JavaScriptアクションをAlpineから直接呼び出しできます。たとえば、$wireオブジェクトを使用して、"bookmark" JavaScriptアクションを呼び出してみましょう。You can call JavaScript actions directly from Alpine using the $wire object. For example, you may use the $wire object to invoke the bookmark JavaScript action:

<button x-on:click="$wire.$js.bookmark()">Bookmark</button>

PHPからの呼び出しCalling from PHP

JavaScriptアクションは、PHPからjs()メソッドを使用して呼び出すこともできます。JavaScript actions can also be called using the js() method from PHP:

<?php

namespace App\Livewire;

use Livewire\Component;

class CreatePost extends Component
{
    public $title = '';

    public function save()
    {
        // …

        $this->js('onPostSaved'); // [tl! highlight]
    }
}
<div>
    <!-- ... -->

    <button wire:click="save">Save</button>
</div>

@script
<script>
    $js('onPostSaved', () => {
        alert('Your post has been saved successfully!')
    })
</script>
@endscript

この例では、save()アクションが完了すると、postSaved JavaScriptアクションを実行し、アラートダイアログを起動します。In this example, when the save() action is finished, the postSaved JavaScript action will be run, triggering the alert dialog.

マジックアクションMagic actions

Livewireでは、カスタムメソッドを定義しなくても、コンポーネントで一般的なタスクを実行できる一連の「マジック」アクションを用意しています。これらのマジックアクションは、Bladeテンプレートで定義したイベントリスナ内で使用できます。Livewire provides a set of "magic" actions that allow you to perform common tasks in your components without defining custom methods. These magic actions can be used within event listeners defined in your Blade templates.

$parent$parent

$parentマジック変数は、子コンポーネントから親コンポーネントのプロパティにアクセスし、親コンポーネントのアクションを呼び出せるようにします。The $parent magic variable allows you to access parent component properties and call parent component actions from a child component:

<button wire:click="$parent.removePost({{ $post->id }})">Remove</button>

上記の例で、親コンポーネントがremovePost()アクションを持っている場合、子コンポーネントは$parent.removePost()を使用して、Bladeテンプレートから直接呼び出し可能です。In the above example, if a parent component has a removePost() action, a child can call it directly from its Blade template using $parent.removePost().

$set$set

$setマジックアクションを使用すると、LivewireコンポーネントのプロパティをBlade テンプレートから直接更新できます。$setを使用するには、更新するプロパティと新しい値を引数に指定します。The $set magic action allows you to update a property in your Livewire component directly from the Blade template. To use $set, provide the property you want to update and the new value as arguments:

<button wire:click="$set('query', '')">Reset Search</button>

この例では、ボタンをクリックすると、コンポーネント内の $queryプロパティを''へ設定するネットワークリクエストをディスパッチします。In this example, when the button is clicked, a network request is dispatched that sets the $query property in the component to ''.

$refresh$refresh

$refreshアクションは、Livewireコンポーネントの再レンダリングを起動します。これは、プロパティ値を変更せずにコンポーネントのビューを更新する場合に役立ちます。The $refresh action triggers a re-render of your Livewire component. This can be useful when updating the component's view without changing any property values:

<button wire:click="$refresh">Refresh</button>

ボタンをクリックすると、コンポーネントを再レンダーし、ビューの最新の変更を確認できます。When the button is clicked, the component will re-render, allowing you to see the latest changes in the view.

$toggle$toggle

$toggleアクションは、Livewireコンポーネント内の booleanプロパティの値を切り替えるために使用します。The $toggle action is used to toggle the value of a boolean property in your Livewire component:

<button wire:click="$toggle('sortAsc')">
    Sort {{ $sortAsc ? 'Descending' : 'Ascending' }}
</button>

この例でボタンをクリックすると、コンポーネント内の$sortAscプロパティが、truefalseの間で切り替わります。In this example, when the button is clicked, the $sortAsc property in the component will toggle between true and false.

$dispatch$dispatch

$dispatchアクションを使用すると、Livewireイベントをブラウザで直接ディスパッチできます。以下は、クリックするとpost-deletedイベントをディスパッチするボタンの例です。The $dispatch action allows you to dispatch a Livewire event directly in the browser. Below is an example of a button that, when clicked, will dispatch the post-deleted event:

<button type="submit" wire:click="$dispatch('post-deleted')">Delete Post</button>

$event$event

$eventアクションは、wire:clickなどのイベントリスナ内で使用します。このアクションを使用すると、トリガーされた実際のJavaScriptイベントへアクセスでき、トリガー要素やその他の関連情報を参照できます。The $event action may be used within event listeners like wire:click. This action gives you access to the actual JavaScript event that was triggered, allowing you to reference the triggering element and other relevant information:

<input type="text" wire:keydown.enter="search($event.target.value)">

上記でユーザーが入力中に、Enterキーを押すと、入力の内容をsearch()アクションのパラメーターとして渡します。When the enter key is pressed while a user is typing in the input above, the contents of the input will be passed as a parameter to the search() action.

Alpineからのマジックアクション使用Using magic actions from Alpine

$wireオブジェクトを使用して、Alpineからマジックアクションを呼び出すこともできます。たとえば、$wireオブジェクトを使用して、$refreshマジックアクションを呼び出すことができます。You can also call magic actions from Alpine using the $wire object. For example, you may use the $wire object to invoke the $refresh magic action:

<button x-on:click="$wire.$refresh()">Refresh</button>

再レンダリングのスキップSkipping re-renders

コンポーネントに呼び出し時、レンダー済みのBladeテンプレートを変更する副作用がないアクションが存在することがあるでしょう。その場合は、アクションメソッドの上に#[Renderless]属性を追加することにより、Livewireのライフサイクルのrender部分をスキップできます。Sometimes there might be an action in your component with no side effects that would change the rendered Blade template when the action is invoked. If so, you can skip the render portion of Livewire's lifecycle by adding the #[Renderless] attribute above the action method.

例を示します。以下のShowPostコンポーネントは、ユーザーがポストの一番下までスクロールしたときに、「表示回数(view count)」をログします。To demonstrate, in the ShowPost component below, the "view count" is logged when the user has scrolled to the bottom of the post:

<?php

namespace App\Livewire;

use Livewire\Attributes\Renderless;
use Livewire\Component;
use App\Models\Post;

class ShowPost extends Component
{
    public Post $post;

    public function mount(Post $post)
    {
        $this->post = $post;
    }

    #[Renderless] // [tl! highlight]
    public function incrementViewCount()
    {
        $this->post->incrementViewCount();
    }

    public function render()
    {
        return view('livewire.show-post');
    }
}
<div>
    <h1>{{ $post->title }}</h1>
    <p>{{ $post->content }}</p>

    <div x-intersect="$wire.incrementViewCount()"></div>
</div>

上記例では、要素がビューポートに入ったときに式を呼び出す Alpineユーティリティのx-intersectを使用します(通常、ユーザーがページの下部にある要素までスクロールしたことを検出するために使用されます)。The example above uses x-intersect[https://alpinejs.dev/plugins/intersect], an Alpine utility that calls the expression when the element enters the viewport (typically used to detect when a user scrolls to an element further down the page).

ご覧のとおり、ユーザーがポストの一番下までスクロールすると、incrementViewCount()を呼び出します。#[Renderless]がアクションに追加されているため、ビューはログに記録されますが、テンプレートは再レンダーされず、ページのどの部分も影響を受けません。As you can see, when a user scrolls to the bottom of the post, incrementViewCount() is invoked. Since #[Renderless] was added to the action, the view is logged, but the template doesn't re-render and no part of the page is affected.

メソッド属性を利用しない場合、またはレンダリングを条件付きでスキップする必要がある場合は、コンポーネントアクションでskipRender()メソッドを呼び出してください。If you prefer to not utilize method attributes or need to conditionally skip rendering, you may invoke the skipRender() method in your component action:

<?php

namespace App\Livewire;

use Livewire\Component;
use App\Models\Post;

class ShowPost extends Component
{
    public Post $post;

    public function mount(Post $post)
    {
        $this->post = $post;
    }

    public function incrementViewCount()
    {
        $this->post->incrementViewCount();

        $this->skipRender(); // [tl! highlight]
    }

    public function render()
    {
        return view('livewire.show-post');
    }
}

セキュリティの考察Security concerns

Livewireコンポーネントのパブリックメソッドは、それを呼び出す関連付いたwire:clickハンドラがなくても、クライアント側から呼び出すことができることに注意してください。このようなシナリオでは、ユーザーはブラウザの開発者ツールからアクションをトリガーすることもできます。Remember that any public method in your Livewire component can be called from the client-side, even without an associated wire:click handler that invokes it. In these scenarios, users can still trigger the action from the browser's DevTools.

以下に、Livewire コンポーネントで見落としがちな脆弱性の3例を示します。それぞれで最初に脆弱なコンポーネントが表示し、その後に安全なコンポーネントを表示します。練習として、解決策を見る前に、最初の例示で脆弱性を見つけてみてください。Below are three examples of easy-to-miss vulnerabilities in Livewire components. Each will show the vulnerable component first and the secure component after. As an exercise, try spotting the vulnerabilities in the first example before viewing the solution.

脆弱性の特定が難しく、自分のアプリケーションを安全に保つ能力について心配になる場合は、これらの脆弱性はすべて、リクエストとコントローラを使用する標準的なWebアプリケーションで適用されることを忘れないでください。コンポーネントメソッドをコントローラーメソッドのプロキシとして、そのパラメーターをリクエスト入力のプロキシとして使用する場合は、既存のアプリケーションセキュリティの知識をLivewireコードへ適用できるはずです。If you are having difficulty spotting the vulnerabilities and that makes you concerned about your ability to keep your own applications secure, remember all these vulnerabilities apply to standard web applications that use requests and controllers. If you use a component method as a proxy for a controller method, and its parameters as a proxy for request input, you should be able to apply your existing application security knowledge to your Livewire code.

アクションパラメータを常に認証するAlways authorize action parameters

コントローラリクエスト入力と同様に、アクションパラメータは任意のユーザー入力であるため、認証することが不可欠です。Just like controller request input, it's imperative to authorize action parameters since they are arbitrary user input.

以下は、ユーザーが自分のポストをすべて1つのページで表示できるShowPostsコンポーネントです。ポストの"Delete"ボタンの1つを使用し、好きな投稿を削除できます。Below is a ShowPosts component where users can view all their posts on one page. They can delete any post they like using one of the post's "Delete" buttons.

以下は、コンポーネントの脆弱なバージョンです。Here is a vulnerable version of the component:

<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use App\Models\Post;

class ShowPosts extends Component
{
    public function delete($id)
    {
        $post = Post::find($id);

        $post->delete();
    }

    public function render()
    {
        return view('livewire.show-posts', [
            'posts' => Auth::user()->posts,
        ]);
    }
}
<div>
    @foreach ($posts as $post)
        <div wire:key="{{ $post->id }}">
            <h1>{{ $post->title }}</h1>
            <span>{{ $post->content }}</span>

            <button wire:click="delete({{ $post->id }})">Delete</button>
        </div>
    @endforeach
</div>

悪意のあるユーザーは、delete()をJavaScriptコンソールから直接呼び出し、アクションに必要なパラメーターを渡すことができることに注意してください。つまり、自分のポストの1つを表示しているユーザーは、所有していないポストのIDをdelete()へ渡すことで、別のユーザーの投稿を削除できます。Remember that a malicious user can call delete() directly from a JavaScript console, passing any parameters they would like to the action. This means that a user viewing one of their posts can delete another user's post by passing the un-owned post ID to delete().

これを防ぐには、削除しようとしているポストをユーザーが所有していることを認証する必要があります。To protect against this, we need to authorize that the user owns the post about to be deleted:

<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use App\Models\Post;

class ShowPosts extends Component
{
    public function delete($id)
    {
        $post = Post::find($id);

        $this->authorize('delete', $post); // [tl! highlight]

        $post->delete();
    }

    public function render()
    {
        return view('livewire.show-posts', [
            'posts' => Auth::user()->posts,
        ]);
    }
}

常にサーバ側で認証するAlways authorize server-side

標準的な Laravelコントローラと同様に、UIでアクションを呼び出すための手段がない場合でも、Livewireアクションはどのユーザーでも呼び出すことができます。Like standard Laravel controllers, Livewire actions can be called by any user, even if there isn't an affordance for invoking the action in the UI.

以下の、BrowsePostsコンポーネントについて考えてみましょう。ここでは、どのユーザーでもアプリケーション内のすべてのポストを表示できますが、管理者だけが投稿を削除できます。Consider the following BrowsePosts component where any user can view all the posts in the application, but only administrators can delete a post:

<?php

namespace App\Livewire;

use Livewire\Component;
use App\Models\Post;

class BrowsePosts extends Component
{
    public function deletePost($id)
    {
        $post = Post::find($id);

        $post->delete();
    }

    public function render()
    {
        return view('livewire.browse-posts', [
            'posts' => Post::all(),
        ]);
    }
}
<div>
    @foreach ($posts as $post)
        <div wire:key="{{ $post->id }}">
            <h1>{{ $post->title }}</h1>
            <span>{{ $post->content }}</span>

            @if (Auth::user()->isAdmin())
                <button wire:click="deletePost({{ $post->id }})">Delete</button>
            @endif
        </div>
    @endforeach
</div>

ご覧のとおり、管理者だけが、"Delete"ボタンを表示できます。ただし、どのユーザーでも、ブラウザの開発者ツールからコンポーネントのdeletePost()を呼び出せます。As you can see, only administrators can see the "Delete" button; however, any user can call deletePost() on the component from the browser's DevTools.

この脆弱性を修正するには、次のようにサーバ上でアクションを認証する必要があります。To patch this vulnerability, we need to authorize the action on the server like so:

<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use App\Models\Post;

class BrowsePosts extends Component
{
    public function deletePost($id)
    {
        if (! Auth::user()->isAdmin) { // [tl! highlight:2]
            abort(403);
        }

        $post = Post::find($id);

        $post->delete();
    }

    public function render()
    {
        return view('livewire.browse-posts', [
            'posts' => Post::all(),
        ]);
    }
}

この変更により、このコンポーネントからポストを削除できるのは管理者のみとなります。With this change, only administrators can delete a post from this component.

危険なメソッドはprotectedprivateに保つKeep dangerous methods protected or private

Livewireコンポーネント内のすべてのpublicメソッドは、クライアントから呼び出し可能です。wire:clickハンドラ内で参照していないメソッドも同様です。意図されていないメソッドがクライアント側から呼び出されるのを防ぐために、それらのメソッドをprotectedまたはprivateとしてマークする必要があります。そうすることにより、機密性の高いメソッドの可視性をコンポーネントのクラスとそのサブクラスに制限し、クライアント側から呼び出されることがないようにできます。Every public method inside your Livewire component is callable from the client. Even methods you haven't referenced inside a wire:click handler. To prevent a user from calling a method that isn't intended to be callable client-side, you should mark them as protected or private. By doing so, you restrict the visibility of that sensitive method to the component's class and its subclasses, ensuring they cannot be called from the client-side.

以前に議論した、BrowsePostsの例を考えてみましょう。ここでは、ユーザーはアプリケーション内のすべてのポストを表示できますが、ポストを削除できるのは管理者のみです。常にサーバ側で承認するのセクションで、サーバ側の承認を追加することでアクションを安全にしました。コードを簡素化するために、ポストの実際の削除を専用のメソッドにリファクタリングすることを想像してください。Consider the BrowsePosts example that we previously discussed, where users can view all posts in your application, but only administrators can delete posts. In the Always authorize server-side[/docs/actions#always-authorize-server-side] section, we made the action secure by adding server-side authorization. Now imagine we refactor the actual deletion of the post into a dedicated method like you might do in order to simplify your code:

// 警告: このスニペットは、やってはいけないことを示しています...
<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use App\Models\Post;

class BrowsePosts extends Component
{
    public function deletePost($id)
    {
        if (! Auth::user()->isAdmin) {
            abort(403);
        }

        $this->delete($id); // [tl! highlight]
    }

    public function delete($postId)  // [tl! highlight:5]
    {
        $post = Post::find($postId);

        $post->delete();
    }

    public function render()
    {
        return view('livewire.browse-posts', [
            'posts' => Post::all(),
        ]);
    }
}
<div>
    @foreach ($posts as $post)
        <div wire:key="{{ $post->id }}">
            <h1>{{ $post->title }}</h1>
            <span>{{ $post->content }}</span>

            <button wire:click="deletePost({{ $post->id }})">Delete</button>
        </div>
    @endforeach
</div>

ご覧のとおり、ポスト削除ロジックをdelete()という専用のメソッドへリファクタリングしました。このメソッドはテンプレート内のどこからも参照されていませんが、ユーザーがその存在を知っていれば、publicであるため、ブラウザの開発者ツールから呼び出せます。As you can see, we refactored the post deletion logic into a dedicated method named delete(). Even though this method isn't referenced anywhere in our template, if a user gained knowledge of its existence, they would be able to call it from the browser's DevTools because it is public.

これを修正するには、メソッドをprotectedまたはprivateとしてマークします。メソッドがprotectedまたはprivateとしてマークすると、ユーザーがそれを呼び出そうとした場合、エラーが投げられます。To remedy this, we can mark the method as protected or private. Once the method is marked as protected or private, an error will be thrown if a user tries to invoke it:

<?php

namespace App\Livewire;

use Illuminate\Support\Facades\Auth;
use Livewire\Component;
use App\Models\Post;

class BrowsePosts extends Component
{
    public function deletePost($id)
    {
        if (! Auth::user()->isAdmin) {
            abort(403);
        }

        $this->delete($id);
    }

    protected function delete($postId) // [tl! highlight]
    {
        $post = Post::find($postId);

        $post->delete();
    }

    public function render()
    {
        return view('livewire.browse-posts', [
            'posts' => Post::all(),
        ]);
    }
}

章選択

パッケージ

設定

バージョン変更
linkv3 linkv2
明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
OS表示
全OS表示
macOSのみ表示
windowsのみ表示
linuxのみ表示
JSフレームワーク
両フレームワーク
Reactのみ表示
Vueのみ表示
JSのみ表示

(JSが存在しない場合は、他を全表示)

和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作