Readouble

Livewire v3 Alpine

Alpine

AlpineJS は、ウェブページにクライアントサイドのインタラクティビティを簡単に追加できる軽量な JavaScript ライブラリです。もともとは、Livewire のようなツールを補完するために構築され、より JavaScript 中心的なユーティリティがアプリケーション全体にインタラクティビティを散りばめるのに役立ちます。AlpineJS[https://alpinejs.dev/] is a lightweight JavaScript library that makes it easy to add client-side interactivity to your web pages. It was originally built to complement tools like Livewire where a more JavaScript-centric utility is helpful for sprinkling interactivity around your app.

Livewire には Alpine が標準で付属しているため、プロジェクトに別途インストールする必要はありません。Livewire ships with Alpine out of the box so there is no need to install it into your project separately.

AlpineJS の使用方法について学ぶのに最適な場所は、Alpine のドキュメントです。The best place to learn about using AlpineJS is the Alpine documentation[https://alpinejs.dev].

基本的な Alpine コンポーネントA Basic Alpine component

このドキュメントの基礎を築くために、Alpine コンポーネントの最もシンプルで有益な例の 1 つを紹介します。ページに数値を表示し、ユーザーがボタンをクリックしてその数値を増やすことができる、小さな「カウンター」です。To lay a foundation for the rest of this documentation, here is one of the most simple and informative examples of an Alpine component. A small "counter" that shows a number on the page and allows the user to increment that number by clicking a button:

<!-- JavaScript のデータオブジェクトを宣言... -->
<div x-data="{ count: 0 }">
    <!-- 現在の "count" 値を要素内にレンダリング... -->
    <h2 x-text="count"></h2>

    <!-- クリックイベントがディスパッチされたときに "count" 値を "1" ずつインクリメント... -->
    <button x-on:click="count++">+</button>
</div>

上記の Alpine コンポーネントは、アプリケーション内の任意の Livewire コンポーネント内で問題なく使用できます。Livewire は、Livewire コンポーネントの更新全体で Alpine の状態を維持します。基本的に、Livewire 以外のコンテキストで Alpine を使用しているかのように、Livewire 内で Alpine コンポーネントを自由に使用できるはずです。The Alpine component above can be used inside any Livewire component in your application without a hitch. Livewire takes care of maintaining Alpine's state across Livewire component updates. In essence, you should feel free to use Alpine components inside Livewire as if you were using Alpine in any other non-Livewire context.

Livewire 内で Alpine を使用するUsing Alpine inside Livewire

Livewire コンポーネント内で Alpine コンポーネントを使用する、より現実的な例を探ってみましょう。Let's explore a more real-life example of using an Alpine component inside a Livewire component.

以下は、データベースから投稿モデルの詳細を表示するシンプルな Livewire コンポーネントです。デフォルトでは、投稿のタイトルのみが表示されます。Below is a simple Livewire component showing the details of a post model from the database. By default, only the title of the post is shown:

<div>
    <h1>{{ $post->title }}</h1>

    <div x-data="{ expanded: false }">
        <button type="button" x-on:click="expanded = ! expanded">
            <span x-show="! expanded">Show post content...</span>
            <span x-show="expanded">Hide post content...</span>
        </button>

        <div x-show="expanded">
            {{ $post->content }}
        </div>
    </div>
</div>

Alpine を使用することで、ユーザーが「Show post content...」ボタンを押すまで投稿のコンテンツを非表示にできます。その時点で、Alpine の expanded プロパティが true に設定され、x-show="expanded" が投稿のコンテンツの表示を Alpine に制御させるために使用されているため、コンテンツがページに表示されます。By using Alpine, we can hide the content of the post until the user presses the "Show post content..." button. At that point, Alpine's expanded property will be set to true and the content will be shown on the page because x-show="expanded" is used to give Alpine control over the visibility of the post's content.

これは、Alpine が輝く場所の例です。Livewire のサーバラウンドトリップをトリガーせずに、アプリケーションにインタラクティビティを追加します。This is an example of where Alpine shines: adding interactivity into your application without triggering Livewire server-roundtrips.

$wire を使用して Alpine から Livewire を制御するControlling Livewire from Alpine using $wire

Livewire 開発者として利用できる最も強力な機能の 1 つは $wire です。$wire オブジェクトは、Livewire 内で使用されるすべての Alpine コンポーネントで使用できるマジックオブジェクトです。One of the most powerful features available to you as a Livewire developer is $wire. The $wire object is a magic object available to all your Alpine components that are used inside of Livewire.

$wire は、JavaScript から PHP へのゲートウェイと考えることができます。これにより、AlpineJS 内から Livewire コンポーネントのプロパティへのアクセスと変更、Livewire コンポーネントのメソッドの呼び出し、その他多くのことが可能になります。You can think of $wire as a gateway from JavaScript into PHP. It allows you to access and modify Livewire component properties, call Livewire component methods, and do much more; all from inside AlpineJS.

Livewire プロパティへのアクセスAccessing Livewire properties

これは、投稿を作成するためのフォームのシンプルな「文字数カウント」ユーティリティの例です。これにより、ユーザーは投稿のコンテンツに含まれる文字数を入力時に即座に確認できます。Here is an example of a simple "character count" utility in a form for creating a post. This will instantly show a user how many characters are contained inside their post's content as they type:

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

    <input wire:model="content" type="text">

    <small>
        Character count: <span x-text="$wire.content.length"></span> <!-- [tl! highlight] -->
    </small>

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

上記の例では、x-text が Alpine に <span> 要素のテキストコンテンツを制御させるために使用されています。x-text は、その内部で任意の JavaScript 式を受け入れ、依存関係が更新されると自動的に反応します。$wire.content を使用して $content の値にアクセスしているため、Alpine は、Livewire から $wire.content が更新されるたびに、テキストコンテンツを自動的に更新します。この場合は wire:model="content" によって更新されます。As you can see x-text in the above example is being used to allow Alpine to control the text content of the <span> element. x-text accepts any JavaScript expression inside of it and automatically reacts when any dependencies are updated. Because we are using $wire.content to access the value of $content, Alpine will automatically update the text content every time $wire.content is updated from Livewire; in this case by wire:model="content".

Livewire プロパティの変更Mutating Livewire properties

これは、$wire を Alpine 内で使用して、投稿を作成するためのフォームの「title」フィールドをクリアする例です。Here is an example of using $wire inside Alpine to clear the "title" field of a form for creating a post.

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

    <button type="button" x-on:click="$wire.title = ''">Clear</button> <!-- [tl! highlight] -->

    <!-- ... -->

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

ユーザーが上記の Livewire フォームに入力する際に、「Clear」を押すと、Livewire からネットワークリクエストを送信せずにタイトルフィールドがクリアされます。インタラクションは「即時」になります。As a user is filling out the above Livewire form, they can press "Clear" and the title field will be cleared without sending a network request from Livewire. The interaction will be "instant".

これを実現するために何が起こっているのかを簡単に説明します。Here's a brief explanation of what's going on to make that happen:

  • x-on:click は、ボタン要素のクリックをリッスンするように Alpine に指示しますx-on:click tells Alpine to listen for a click on the button element
  • クリックされると、Alpine は提供された JS 式 $wire.title = '' を実行しますWhen clicked, Alpine runs the provided JS expression: $wire.title = ''
  • $wire は Livewire コンポーネントを表すマジックオブジェクトであるため、コンポーネントのすべてのプロパティに JavaScript から直接アクセスまたは変更できますBecause $wire is a magic object representing the Livewire component, all properties from your component can be accessed or mutated straight from JavaScript
  • $wire.title = '' は、Livewire コンポーネントの $title の値を空の文字列に設定します$wire.title = '' sets the value of $title in your Livewire component to an empty string
  • wire:model のような Livewire ユーティリティは、サーバラウンドトリップを送信することなく、この変更に即座に反応しますAny Livewire utilities like wire:model will instantly react to this change, all without sending a server-roundtrip
  • 次の Livewire ネットワークリクエストで、$title プロパティがバックエンドで空の文字列に更新されますOn the next Livewire network request, the $title property will be updated to an empty string on the backend

Livewire メソッドの呼び出しCalling Livewire methods

Alpine は、$wire で直接呼び出すだけで、Livewire のメソッド/アクションを簡単に呼び出すこともできます。Alpine can also easily call any Livewire methods/actions by simply calling them directly on $wire.

これは、入力で "blur" イベントをリッスンし、フォームの保存をトリガーするために Alpine を使用する例です。"blur" イベントは、ユーザーが "tab" を押して現在の要素からフォーカスを外し、ページ上の次の要素にフォーカスするときにブラウザによってディスパッチされます。Here is an example of using Alpine to listen for a "blur" event on an input and triggering a form save. The "blur" event is dispatched by the browser when a user presses "tab" to remove focus from the current element and focus on the next one on the page:

<form wire:submit="save">
    <input wire:model="title" type="text" x-on:blur="$wire.save()">  <!-- [tl! highlight] -->

    <!-- ... -->

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

通常、この状況では wire:model.blur="title" を使用しますが、Alpine を使用してこれを実現する方法を示すのに役立ちます。Typically, you would just use wire:model.blur="title" in this situation, however, it's helpful for demonstration purposes how you can achieve this using Alpine.

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

$wire メソッドの呼び出しにパラメータを渡すだけで、Livewire メソッドにパラメータを渡すこともできます。You can also pass parameters to Livewire methods by simply passing them to the $wire method call.

次のような deletePost() メソッドを持つコンポーネントを考えてみましょう。Consider a component with a deletePost() method like so:

public function deletePost($postId)
{
    $post = Post::find($postId);

    // Authorize user can delete...
    auth()->user()->can('update', $post);

    $post->delete();
}

次に、次のように $postId パラメータを Alpine から deletePost() メソッドに渡すことができます。Now, you can pass a $postId parameter to the deletePost() method from Alpine like so:

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

一般的に、$postId のようなものは Blade で生成されます。Blade を使用して、Alpine が deletePost() に渡す $postId を決定する例を次に示します。In general, something like a $postId would be generated in Blade. Here's an example of using Blade to determine which $postId Alpine passes into deletePost():

@foreach ($posts as $post)
    <button type="button" x-on:click="$wire.deletePost({{ $post->id }})">
        Delete "{{ $post->title }}"
    </button>
@endforeach

ページに 3 つの投稿がある場合、上記の Blade テンプレートはブラウザで次のようにレンダリングされます。If there are three posts on the page, the above Blade template will render to something like the following in the browser:

<button type="button" x-on:click="$wire.deletePost(1)">
    Delete "The power of walking"
</button>

<button type="button" x-on:click="$wire.deletePost(2)">
    Delete "How to record a song"
</button>

<button type="button" x-on:click="$wire.deletePost(3)">
    Delete "Teach what you learn"
</button>

ご覧のとおり、Blade を使用して、異なる投稿 ID を Alpine の x-on:click 式にレンダリングしました。As you can see, we've used Blade to render different post IDs into the Alpine x-on:click expressions.

Blade パラメータの「落とし穴」Blade parameter "gotchas"

これは非常に強力なテクニックですが、Blade テンプレートを読むときに混乱する可能性があります。どの部分が Blade で、どの部分が Alpine であるかを一目で判断するのは難しい場合があります。したがって、ページにレンダリングされる HTML を調べて、レンダリングされると予想されるものが正確であることを確認すると役立ちます。This is an extremely powerful technique, but can be confusing when reading your Blade templates. It can be hard to know which parts are Blade and which parts are Alpine at first glance. Therefore, it's helpful to inspect the HTML rendered on the page to make sure what you are expecting to be rendered is accurate.

これは、人々を混乱させる一般的な例です。Here's an example that commonly confuses people:

ID の代わりに、Post モデルがインデックスに UUID を使用するとします(ID は整数で、UUID は長い文字列です)。Let's say, instead of an ID, your Post model uses UUIDs for indexes (IDs are integers, and UUIDs are long strings of characters).

ID で行ったのと同じように次をレンダリングすると、問題が発生します。If we render the following just like we did with an ID there will be an issue:

<!-- Warning: this is an example of problematic code... -->
<button
    type="button"
    x-on:click="$wire.deletePost({{ $post->uuid }})"
>

上記の Blade テンプレートは、HTML で次のようにレンダリングされます。The above Blade template will render the following in your HTML:

<!-- Warning: this is an example of problematic code... -->
<button
    type="button"
    x-on:click="$wire.deletePost(93c7b04c-c9a4-4524-aa7d-39196011b81a)"
>

UUID 文字列の周りに引用符がないことに注意してください。Alpine がこの式を評価すると、JavaScript はエラーをスローします: "Uncaught SyntaxError: Invalid or unexpected token"。Notice the lack of quotes around the UUID string? When Alpine goes to evaluate this expression, JavaScript will throw an error: "Uncaught SyntaxError: Invalid or unexpected token".

これを修正するには、次のように Blade 式の周りに引用符を追加する必要があります。To fix this, we need to add quotations around the Blade expression like so:

<button
    type="button"
    x-on:click="$wire.deletePost('{{ $post->uuid }}')"
>

これで、上記のテンプレートは正しくレンダリングされ、すべてが期待どおりに機能します。Now the above template will render properly and everything will work as expected:

<button
    type="button"
    x-on:click="$wire.deletePost('93c7b04c-c9a4-4524-aa7d-39196011b81a')"
>

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

$wire.$refresh() を使用して、Livewire コンポーネントを簡単にリフレッシュできます(コンポーネントの Blade ビューを再レンダリングするためにネットワークラウンドトリップをトリガーします)。You can easily refresh a Livewire component (trigger network roundtrip to re-render a component's Blade view) using $wire.$refresh():

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

$wire.entangle を使用した状態の共有Sharing state using $wire.entangle

ほとんどの場合、$wire は Alpine から Livewire の状態を操作するために必要なすべてです。ただし、Livewire は、Livewire の値と Alpine の値を同期させるために使用できる追加の $wire.entangle() ユーティリティを提供します。In most cases, $wire is all you need for interacting with Livewire state from Alpine. However, Livewire provides an additional $wire.entangle() utility that can be used to keep values from Livewire in-sync with values in Alpine.

説明するために、showDropdown プロパティが $wire.entangle() を使用して Livewire と Alpine の間で絡み合っているこのドロップダウンの例を考えてみましょう。絡み合いを使用することで、Alpine と Livewire の両方からドロップダウンの状態を制御できるようになりました。To demonstrate, consider this dropdown example with its showDropdown property entangled between Livewire and Alpine using $wire.entangle(). By using entanglement, we are now able to control the state of the dropdown from both Alpine and Livewire:

use Livewire\Component;

class PostDropdown extends Component
{
    public $showDropdown = false;

    public function archive()
    {
        // ...

        $this->showDropdown = false;
    }

    public function delete()
    {
        // ...

        $this->showDropdown = false;
    }
}
<div x-data="{ open: $wire.entangle('showDropdown') }">
    <button x-on:click="open = true">Show More...</button>

    <ul x-show="open" x-on:click.outside="open = false">
        <li><button wire:click="archive">Archive</button></li>

        <li><button wire:click="delete">Delete</button></li>
    </ul>
</div>

ユーザーは Alpine でドロップダウンをすぐに切り替えることができますが、「Archive」のような Livewire アクションをクリックすると、ドロップダウンは Livewire から閉じるように指示されます。Alpine と Livewire の両方が、それぞれのプロパティを自由に操作でき、もう一方のプロパティは自動的に更新されます。A user can now toggle the dropdown immediately with Alpine, but when they click a Livewire action like "Archive", the dropdown will be told to close from Livewire. Both Alpine and Livewire are welcome to manipulate their respective properties, and the other will automatically update.

デフォルトでは、状態の更新は、次の Livewire リクエストまで遅延されます(クライアント側で変更されますが、サーバ側ではすぐには変更されません)。ユーザーがクリックしたときに状態をサーバ側ですぐに更新する必要がある場合は、次のように .live 修飾子をチェーンします。By default, updating the state is deferred (changes on the client, but not immediately on the server) until the next Livewire request. If you need to update the state server-side as soon as the user clicks, chain the .live modifier like so:

<div x-data="{ open: $wire.entangle('showDropdown').live }">
    ...
</div>

lightbulb Tip: $wire.entangle は必要ないかもしれません ほとんどの場合、値を絡み合わせるのではなく、$wire を使用して Alpine から Livewire プロパティに直接アクセスすることで、必要なものを実現できます。1 つのプロパティに依存するのではなく、2 つのプロパティを絡み合わせると、頻繁に変更される深くネストされたオブジェクトを使用する場合に、予測可能性とパフォーマンスの問題が発生する可能性があります。このため、$wire.entangle は、バージョン 3 以降の Livewire のドキュメントで強調されなくなりました。[!tip] You might not need $wire.entangle In most cases, you can achieve what you want by using $wire to directly access Livewire properties from Alpine rather than entangling them. Entangling two properties rather than relying on one can cause predictability and performance issues when using deeply nested objects that change frequently. For this reason, $wire.entangle has been de-emphasized in Livewire's documentation starting with version 3.

warning Warning! @@entangle ディレクティブの使用は控えてください Livewire バージョン 2 では、Blade の @@entangle ディレクティブを使用することをお勧めしました。これは v3 では当てはまりません。$wire.entangle() は、より堅牢なユーティリティであり、特定の DOM 要素を削除する際の問題 を回避するため、推奨されます。[!warning] Refrain from using the @@entangle directive In Livewire version 2, it was recommended to use Blade's @@entangle directive. That is no longer the case in v3. $wire.entangle() is preferred as it is a more robust utility and avoids certain issues when removing DOM elements[https://github.com/livewire/livewire/pull/6833#issuecomment-1902260844].

JavaScript ビルドで Alpine を手動でバンドルするManually bundling Alpine in your JavaScript build

デフォルトでは、Livewire と Alpine の JavaScript は、各 Livewire ページに自動的に挿入されます。By default, Livewire and Alpine's JavaScript is injected onto each Livewire page automatically.

これはよりシンプルなセットアップに最適ですが、独自の Alpine コンポーネント、ストア、およびプラグインをプロジェクトに含めることができます。This is ideal for simpler setups, however, you may want to include your own Alpine components, stores, and plugins into your project.

ページ上の独自の JavaScript バンドルを介して Livewire と Alpine を含めるのは簡単です。To include Livewire and Alpine via your own JavaScript bundle on a page is straightforward.

まず、次のように、レイアウトファイルに @livewireScriptConfig ディレクティブを含める必要があります。First, you must include the @livewireScriptConfig directive in your layout file like so:

<html>
<head>
    <!-- ... -->
    @livewireStyles
    @vite(['resources/js/app.js'])
</head>
<body>
    {{ $slot }}

    @livewireScriptConfig <!-- [tl! highlight] -->
</body>
</html>

これにより、Livewireは、アプリが適切に実行されるために必要な特定の設定をバンドルに提供できます。This allows Livewire to provide your bundle with certain configuration it needs for your app to run properly.

これで、resources/js/app.jsファイルで、次のようにLivewireとAlpineをインポートできます。Now you can import Livewire and Alpine in your resources/js/app.js file like so:

import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';

// ここにAlpineのディレクティブ、コンポーネント、またはプラグインを登録します...

Livewire.start()

以下は、アプリケーションで"x-clipboard"というカスタムAlpineディレクティブを登録する例です。Here is an example of registering a custom Alpine directive called "x-clipboard" in your application:

import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';

Alpine.directive('clipboard', (el) => {
    let text = el.textContent

    el.addEventListener('click', () => {
        navigator.clipboard.writeText(text)
    })
})

Livewire.start()

これで、x-clipboardディレクティブは、LivewireアプリケーションのすべてのAlpineコンポーネントで使用できるようになります。Now the x-clipboard directive will be available to all your Alpine components in your Livewire application.

章選択

パッケージ

設定

バージョン変更
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に保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作