【Livewire】JavaScriptでサーバーサイドの値変更したり、関数を実行したい。

こんにちは。
日本語ドキュメントはよ。
只野です。

最近は「Laravel 11」とスタートパッケージで最近押してる「Jetstream」を導入してWebアプリを作成しています。

そうすると「Livewire」というフレームワークが利用可能になり、これがまた便利。

Livewire」は簡単に言うと、ページリフレッシュを掛けずに、「JavaScript」などを利用して部分的にページを部分更新する、今風のWeb画面が、サーバーサイド(PHP)に記載するだけで作成できるというフレームワークです。

前は「ajax」とか使ったりしてサーバーサイド、クライアントサイドのソースをうぉぉぉぉお!って書いてましたが、それがサーバーサイドだけ書けばよいのです。こいつは素晴らしい!

実装速度が圧倒的にあがりますね!

それぞれの詳細は公式ページを見てください。

Livewire

Laravel11 + Jetstream

だがしかし!

どちらも公式日本語ドキュメントはなく!

Web検索での情報も少ない!

なので公式ドキュメントをGoogle翻訳して自分が欲しい情報を調べたり、直接ソース読んだりと中々遠回りな事して情報をかき集めながら使ってる感じです…

これだと本当に小さい箇所でよく躓くんですよ!

フレームワークは強力なのですが、使うまでのハードルが高いんですよ!日本語しかできないとね!英語勉強したほうが色々早いのではないかとか考えちゃいますよ!

脱線しました。

どんな感じで躓くかというと、例えば“JavaScriptを使って、独自にクライアントサイドで画面項目の値を直接変更”したとします。

思う動きとしては、Submit時にサーバーサイドに変更した画面項目の値が送信される事なんですが、“変更した値は送信されません”

普通に考えたらSubmit時に画面の値を全部送信してくれそうなものですが、「Livewire」は違います。

Livewire」はフレームワークでサーバーサイド、クライアントサイドのデータ連携が行われます。

ここで「JavaScript」が大きく係わってます。

Livewire」はサーバーサイド(PHP)を書けばよいだけですが、フレームワークではクライアントサイド(JavaScript)で一生懸命処理が行われています。

サーバーサイドとクライアントサイドのデータ連携も「Livewire」がサーバーサイドの変数を「JavaScript」変数として自動で再定義して管理が行われます。

このため、値の変更を実装したいだけでも、「Livewire」で管理している「JavaScript」変数の値を書き換える必要があります!

Livewire」で管理される、「JavaScript」変数を利用しないと、独自にクライアントサイドの処理を記載して、画面項目の値を直接変更しても「Livewire」では値の変更と見なしてくれません!

Livewire」でクライアントサイドの処理を組む具体的な方法は下記となります。

<x-slot name="header">
    <h2 class="font-semibold text-xl text-gray-800 leading-tight">
        ユーザー登録
    </h2>
  </x-slot>
  <div>
    <div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
      <form wire:submit="save">

            <div class="col-span-6 sm:col-span-4">
              <x-label for="name" value="ユーザー名" />
              <x-input id="name" type="text" class="mt-1 block w-full bg-pink-100" wire:model="form.name" />
              <x-input-error for="form.name" class="mt-2" />
            </div>

            <div class="col-span-6 sm:col-span-4">
              <x-label for="furigana" value="ユーザー名ふりがな" />
              <x-input id="furigana" type="text" class="mt-1 block w-full" wire:model="form.furigana" />
              <x-input-error for="form.furigana" class="mt-2" />
            </div>

            <div class="col-span-6 sm:col-span-4">
              <x-label for="email" value="メールアドレス" />
              <x-input id="email" type="email" class="mt-1 block w-full bg-pink-100" wire:model="form.email" />
              <x-input-error for="form.email" class="mt-2" />
            </div>

            <x-buttons.button-insert id="insert-button" class="mr-2">
                {{ __('登録') }}
            </x-buttons.button-insert>

            <x-buttons.button-update id="next-insert-button">
                {{ __('続けて登録') }}
            </x-buttons.button-update>

<!-- ここから -->
        @script
        <script>
          $(function(){
            $(document).on("click", '[id=insert-button]', function() {
              $wire.form.nextInsert = false;
            });

            $(document).on("click", '[id=next-insert-button]', function() {
              $wire.form.nextInsert = true;
            });
          });
        </script>
        @endscript
<!-- ここまでが重要! -->
      </form>
    </div>
  </div>

実装箇所は各々作成する画面テンプレートファイル(blade)に実装します。

Livewire」のテンプレートファイルはデフォルト設定だと下記に収納します。

  • ドキュメントルート\resources\views\livewire\各々のファイル名

サンプルはボタン押下状態をクライアントサイドで切り替えている例となります。

サーバーサイドには「$this->form->nextInsert」という変数が存在します。

ここで重要なのが「@script」で独自の「JavaScript」を囲む事。これにより「Livewire」のクライアントサイドのフレームワークが利用できるようになります。

$wire」変数が「Livewire」が提供するクライアントサイドのフレームワークになります。

$wire」変数を通してじゃないとクライアントサイド、サーバーサイドの値を同期させる事はできません。

$wire」変数の配下には、サーバーサイドでpublicと定義したプロパティ、関数が全て収容されています。

収容形式は単純に「$wire」配下にサーバーサイド定義している階層で収容されます。

例えばサーバーサイドで下記のように定義したとします。

<?php

namespace App\Livewire\User;

/**
 * ユーザー登録コンポーネント(Livewire)
 */
class CreateUser extends Component
{
    public UserForm $form;
    // UserFormには下記プロパティが存在
    // public $name;
    // public $furigana;
    // public $nextInsert;

    /*
    * 登録処理を行います。
    */
    public save() 
    {
        // 登録関連処理。
    }
}

$wire」変数の配下には下記のように収容されます。

<script>
// ユーザーフォームの収容結果
$wire.form.name;
$wire.form.furigana;
$wire.form.nextInsert;

// 関数の収容結果
$wire.save()
</script>

関数も収容してくれているのが便利で、例えばサーバーサイドに「save」というメソッドがあれば、「$wire.save()」とクライアントサイドで記載すると該当のサーバーサイド処理を実行することができます。

詳しい使い方は下記公式ドキュメントを参照してください。

Livewire JavaScript利用方法

Livewire」を利用したWebシステムでクライアントサイドから値更新したので反映されない!といった症状は間違いなく「$wire」を利用していないからです。

Livewire」を触りたての頃の私はここで結構はまっていました。

使う前にフレームワークの仕組みをそもそも理解しろって話ですね。

本日はこの辺で

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です