LaravelのInertia+Vueの組み合わせでフロントエンド的な画面を作成する【応用編】
LivewireとInertiaによるLaravelのフロントエンド的画面作成入門 第4回
もうひとつのフォームの実装方法useForm()ヘルパー
Inertiaでフォームを実装する方法として、Formコンポーネントの他に、useForm()ヘルパーがあります。カクテル情報の編集画面を題材に、このuseForm()ヘルパーを紹介します。
編集画面の表示処理コード
カクテルリスト画面の詳細表示部分に関して、図4のように[このカクテルの編集はこちら]というリンクを[閉じる]ボタンの上に追加したとします。
このリンク部分に関するコードは、カクテル編集画面表示へのパスを/showCocktailEditとするならば、リスト5のようになります。
<script setup lang="ts">
:
const showCocktailEditLink = ref(""); // (1)
const showDetail = (id: number) => { // (2)
:
showCocktailEditLink.value = `/showCocktailEdit/${id}`; // (3)
};
:
</script>
<template>
:
<section v-if="detailSection">
:
<Link v-bind:href="showCocktailEditLink">このカクテルの編集はこちら</Link><br> // (4)
<button v-on:click="closeDetail">閉じる</button>
</section>
</template>
リスト5の(1)でカクテル編集画面へのパス文字列を表すリアクティブな変数としてshowCocktailEditLinkを用意します。そして、カクテルリスト中のカクテル名をクリックしたときに実行されるメソッドである(2)のshowDetail内の(3)で、カクテルIDを元にルートパラメータ付きのリンクパスを生成します。そのリンクパスを元にLinkコンポーネントを利用してリンクを生成しているのが(4)です。
この/showCocktailEditのパスに対して呼び出されるアクションメソッドを、同名のshowCocktailEdit()とすると、リスト6のコードとなります。
class CocktailController extends Controller
{
:
public function showCocktailEdit(Cocktail $cocktail)
{
return Inertia::render("cocktail/CocktailEdit", ["cocktail" => $cocktail]);
}
}
リスト6では、ルートモデルバインディングを利用してCocktailオブジェクトを引数として受け取り、それをそのまま画面に渡すデータとしてInertia::render()メソッドの第2引数に利用しています。これで、第1引数で指定しているCocktailEditコンポーネントに処理が移管されます。
useForm()を利用する場合は通常のformタグ
では、そのCocktailEditコンポーネントはどのようなコードになるかというと、リスト7のようになります。
<script setup lang="ts">
import {Link, useForm} from "@inertiajs/vue3";
//Cocktailインターフェースを定義。
interface Cocktail {
id: number;
name: string;
price: number;
}
//Propsインターフェースを定義。
interface Props { // (1)
cocktail: Cocktail; // (1)
} // (1)
//Propsの取得。
const props = defineProps<Props>(); // (1)
//useForm()を使ってフォームオブジェクトを定義。
const form = useForm({ // (2)
id: props.cocktail.id, // (3)
cocktailName: props.cocktail.name, // (4)
cocktailPrice: props.cocktail.price, // (5)
});
</script>
<template>
<h1>カクテル管理</h1>
<section>
<h2>カクテル追加</h2>
<form v-on:submit.prevent="form.post('/editCocktail')"> // (6)
<label for="cocktailName">カクテル名</label>
<input type="text" v-model="form.cocktailName" id="cocktailName"> // (7)
<div v-if="form.errors.cocktailName">{{ form.errors.cocktailName }}</div><br> // (8)
<label for="cocktailPrice">金額</label>
<input type="number" v-model="form.cocktailPrice" id="cocktailPrice"> // (9)
<div v-if="form.errors.cocktailPrice">{{ form.errors.cocktailPrice }}</div><br> // (10)
<button type="submit">更新</button>
</form>
<Link href="/cocktailList">カクテルリストへ戻る</Link>
</section>
</template>
リスト7のポイントは、フォームの定義にFormコンポーネントを利用するのではなく、(6)のように通常のformタグを利用している点です。
ただし、formタグのサブミット実行の際に、通常のリクエスト送信ではなく、スクリプトブロックの処理が実行されるように、v-on:submit.preventを定義しています。そして、実行されるメソッドもスクリプトブロックで独自定義したものではなく、(2)のuseForm()によって生成されたフォームオブジェクトのメソッドを実行しています。
このuseForm()は、Inertiaに用意されたヘルパー関数であり、フォームに関する処理を一手に引き受けてくれるオブジェクトを生成してくれます。
useForm()の引数はリクエストパラメータを定義
useForm()の引数として、サーバサイドに送信したいリクエストパラメータをプロパティとして定義したオブジェクトを渡します。
リスト7では、(3)でカクテルID(リクエストパラメータ名id)を初期値props.cocktail.id、(4)でカクテル名(リクエストパラメータ名cocktailName)を初期値props.cocktail.name、(5)でカクテルの金額(リクエストパラメータ名cocktailPrice)を初期値props.cocktail.priceとして定義しています。
この時点で(1)で定義した通り、Propsとして渡されたCocktailオブジェクトの値、すなわちリスト6のInertia::render()の第2引数で渡されたカクテル情報の値が、useForm()によって生成されたformオブジェクトに初期値として格納されたことになります。
もちろん、これらの値は、テンプレートブロックでもリアクティブな変数として利用できます。実際、カクテル名の入力欄である(7)とカクテルの金額の入力欄である(9)では、v-modelを利用して入力値との双方向データバインディングを行っています。
リクエスト送信もフォームオブジェクトのメソッドを利用
先述の通り、フォームのサブミットイベントにおいて実行されているのは、このフォームオブジェクトのpost()メソッドとなっています。
このように、実際のリクエスト送信もフォームオブジェクトに用意されたメソッドを利用し、引数として送信先パスを指定します。もちろん、ここで利用したpost()メソッドの他に、リクエストメソッドに応じて、get()、put()、patch()、delete()の各メソッドが用意されています。
これらのメソッドが実行された際に送信されるデータは、その時点でフォームオブジェクトが保持しているプロパティの値となります。リスト7で言えば、(3)のid、(4)のcocktailName、(5)のcocktailPriceが送信されます。ここで特徴的なのは、idです。通常、このようなidの値は変更不可なため、入力コントロールは用意せずにhiddenタグで送信する仕組みになっています。それがリスト7を見るとわかるように、不要となります。
バリデーションメッセージもフォームオブジェクト内に格納される
そのようにして送信された先で実行されるアクションメソッドにおいて、リスト3と同様にサーバサイドバリデーションを実行した場合、そのバリデーションメッセージもフォームオブジェクト内にerrorsプロパティとして格納されます。それらのメッセージをv-ifを利用してメッセージが存在する場合に表示させているのが、リスト7の(8)と(10)です。
まとめ
Laravelのフロントエンド的画面作成方法を紹介する連載の最終回は、いかがだったでしょうか。今回は、Inertiaによる画面遷移、およびフォームデータの取り扱いを紹介しました。
4回にわたって紹介してきたLaravelのフロントエンド的画面作成方法もこれで終了です。本連載で紹介しきれなかった細かい仕様などもありますが、LivewireとInertiaの使い方の大枠は紹介できたのではないかと思います。この連載が読者諸兄姉に少しでも役に立ったのならば、これほどうれしいことはありません。
この記事は参考になりましたか?
既に会員の方はを行ってください。
- LivewireとInertiaによるLaravelのフロントエンド的画面作成入門連載記事一覧
-
- LaravelのInertia+Vueの組み合わせでフロントエンド的な画面を作成する【応用...
- LaravelのInertia+Vueの組み合わせでフロントエンド的な画面を作成する【基本...
- Livewireを使ってフロントエンド的な画面を作成する
- この記事の著者
-
WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)
<WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書、記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook <個人紹介>WINGSプロジェクト所属のテクニカルライター。Web系製作会社のシステム部門、SI会社を経てフリーランスとして独立。屋号はSarva(サルヴァ)。HAL大阪の非常勤講師を兼務。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数。
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
