Inertia.jsのルーティングとレスポンス作成 Inertia入門#3

Inertia.js入門#3 ルーティングとレスポンス Laravel

Laravel8でjetstreamを入れるとLimewireかInertiaかを選べます。この記事ではInertiaを使ってルーティングやInertiaレスポンスの返し方を解説します。

前回の記事ではInertia.jsをLaravelにインストールして、HelloWorldを表示させるところまで行いました。今回はその続きですのでぜひ前回の記事と合わせてお読みください。

ソースコード

ソースコードはGitHubに公開しています。

Inertiaレスポンス

コントローラーの作成

前回HelloWorldを表示させたときは、直接web.phpでInertiaビューを返しました。静的なページであればそれでも構いませんが、実際は何らかのデータを表示したり、編集削除ができるようにすることが多いと思います。

そうしたデータを取得してビューに渡す役割を果たすのがコントローラーです。今回はブックマークを表示する「BookmarkController」コントローラーを作成していきます。

artisanでコントローラーファイルのテンプレートを作成します。

make app

Laravelコンテナに入ってから

php artisan make:controller BookmarkController

「app/Http/Controllers/BookmarkController.php」というコントローラーファイルが作成されます。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class BookmarkController extends Controller
{
    //この下にリクエストがあった場合の処理を記述します。    
}

indexアクションを追加

Inertiaをuseしてクラス名だけでInertiaを使用できるようにします。

use Inertia\Inertia;

BookmarkControllerクラスにindexアクションを追加します。

    public function index () 
    {
        $bookmarks = [
            [
                'title' => 'SOHO MIND',
                'url' => 'https://blog.shipweb.jp/',
            ],
            [
                'title' => 'Youtube Checker',
                'url' => 'https://ytc.shipweb.jp/',
            ],
        ];

        return Inertia::render('Bookmark/Index',['bookmarks' => $bookmarks]);
    }

3-12行目:ブックマークのデータを配列で用意します。本来ならモデルから取得しますが、今回は簡略化のため直接データを指定しています。
14行目:Inertiaレスポンスを返しています。「Inertia::render」でInertiaでビューを処理するための関数を呼び出します。引数は、1番目が表示するページ、2番目がそのページに渡すデータです。

BookmarkController全体はこのようになります。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Inertia\Inertia;

class BookmarkController extends Controller
{
    //    
    public function index () 
    {
        $bookmarks = [
            [
                'title' => 'SOHO MIND',
                'url' => 'https://blog.shipweb.jp/',
            ],
            [
                'title' => 'Youtube Checker',
                'url' => 'https://ytc.shipweb.jp/',
            ],
        ];

        return Inertia::render('Bookmark/Index',['bookmarks' => $bookmarks]);
    }
}

ルートの追加

「routes/web.php」に、「/Bookmark」というURLにアクセスしたときに、「BookmarkController」クラスの「index」メソッドを呼び出すルートを追加します。

//web.phpの最後に追加
Route::get('/Bookmark',[App\Http\Controllers\BookmarkController::class, 'index']);

ページの作成

ブックマーク一覧を表示するVueコンポーネントを作成します。先ほどコントローラーで返すInertiaレスポンスはこのようなものでした。

return Inertia::render('Bookmark/Index',['bookmarks' => $bookmarks]);

1番目の引数で表示するページを指定していました。ここでは「Bookmark/Index」というページを指定しています。このページはVueコンポーネントですので、「Bookmark」というディレクトリを作成し、その下に「Index.vue」というファイル名でVueコンポーネントファイルを作成します。

Inertiaページの置き場所は「resources/js/Pages/」配下になるため、Index.vueファイルのパスは「resources/js/Pages/Bookmark/Index.vue」となります。

<script setup>
defineProps({ bookmarks: Array })
</script>

<template>
    <h2 class="text-lg border-b py-2">ブックマーク一覧</h2>
    <ul class="list-disc list-inside p-2">
        <li v-for="bookmark in bookmarks">
            <a :href="bookmark.url" target=_blank class="text-blue-700" >{{ bookmark.title }}</a>
        </li>
    </ul>
</template>

内容は一般的なVueコンポーネントと変わりません。propsに、コントローラーで返すよう指定したInertiaレスポンスの2番目の引数が入ります。連想配列の名前と、propsで受け取るデータの名前を合わせてください。この場合、「bookmarks」がブックマークの配列データが入った変数名となります。

表示確認

ファイルを保存して、動作確認してみましょう。Vueファイルを編集しているので、JSファイルのコンパイルが必要になります。

//まだLaravelのコンテナに入っている場合は一旦出ます
exit
//Nodeが入っているwebコンテナへ入ります
make web
npm run dev

この連載記事の「DockerでLaravelの開発環境を構築する」の方法で環境を作っている場合は「make npm-dev」コマンドでwebコンテナで「npm run dev」コマンドが実行出来ます。

http://localhost/Bookmark」にアクセスしてブックマーク一覧が表示されるか確認しましょう。次のように表示されれば成功です。

ブックマーク一覧

名前付きルート

ルートを直接記述する場合

前回HelloWorldページからホーム画面に戻るためのInertia-linkを作成したときのリンク先はこのようになっていました。

        <Link href="/" class="text-sm text-blue-700 underline">
                ホームへ戻る
        </Link>

「href=”/”」と、直接URLを指定しています。この書き方でもInertia-linkのおかげでXHRリクエストが代わりに行われてレスポンスもJSONで返って来ました。

名前付きルートを使用する場合

Laravelでは、URLを記述する時に直接URLを記述する代わりに、ルートにあらかじめ付けておいた名前と渡したパラメーターで適切なURLを生成してくれる機能があり、Inertia.jsでもそれが使えます。

名前付きルートはこんな時に便利
  • 後からパスを変えたくなった時に、ルート定義ファイルだけを変更するだけで済む。(コントローラーやビューの中の該当パスを探して変更する手間が省ける)
  • 存在しないルートの場合はエラーが出るため、ミスに気が付きやすい。

名前付きルートの作り方

ルート定義の後にnameメソッドをルート名を渡してチェインします。(末尾に->name(“ルート名”);を追加します。)

このブックマーク一覧を表示するルートに、「bookmark.index」という名前を付ける場合このように末尾にnameメソッドを追加します。

Route::get('/Bookmark',[App\Http\Controllers\BookmarkController::class, 'index'])->name('bookmark.index');

Inertiaページで名前付きルートからURLを生成する

LaravelでInertia.jsを使用する場合、Ziggyライブラリをインストールすることで、Vueコンポーネントの中で「route」メソッドにルート名を渡して呼び出すことで、定義しておいた名前付きルートのURLを取得できます。

Ziggyのインストール

//Laravelコンテナに入ってcomposerでインストール
make app
composer require tightenco/ziggy

次に、app.blade.phpの@vite('resources/js/app.js')の前の行に@routesを追加します。

//略
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
    @routes
    @vite('resources/js/app.js')
    @inertiaHead
  </head>
//略

これでJavaScriptでroute関数が使用できるようになりました。Vueコンポーネントからグローバルにroute関数を使用できるよう、app.jsでappのグローバルプロパティにrouteを追加します。

//略  
setup({ el, App, props, plugin }) {
    const app = createApp({ render: () => h(App, props) });
    app.config.globalProperties.route = route;
    app.use(plugin);
    app.mount(el);
  },
//略

これでroute関数を使う準備が整いました。

ブックマーク一覧のタイトルに、名前付きルートで作成したURLを使って自身のページへのリンクを張ってみます。H2タグの中を以下のように書き換えます。

//変更前
    <h2 class="text-lg border-b py-2">ブックマーク一覧</h2> 

//変更後
    <h2 class="text-lg border-b py-2">
        <Link :href="route('bookmark.index')" class="text-blue-700 underline">
        ブックマーク一覧
        </Link>
    </h2>

:href=”route(‘bookmark.index’)” がポイントになります。
routeメソッドを’bookmark.index’というルート名の引数を渡して呼び出すことで「/Bookmark」というURLを取得できます。
hrefの前に「:」をつけると、Vueの動作で動的にその属性値を解釈します。つまり、その中の関数などが実行されて、属性値として用いられます。

<Link>を使うために、コンポーネントをインポートします。<Script>を次のように変更します。

<script setup>
import { Link } from '@inertiajs/vue3'

defineProps({ bookmarks: Array })
</script>

<script setup> のスコープ内でインポートしているため、テンプレート内で<Link>を直接使用できます。

表示確認

タイトルの「ブックマーク一覧」にリンクが付き、リンク先が「localhost/Bookmark」になっていることを確認してください。

まとめ

今回の内容
  • Inertiaレスポンスは「Inertia::render(ページ,データ);」で作成する
  • Vueではpropsで渡されたデータを受け取る
  • 名前付きルートは「route(ルート名)」でURLを生成できる

次回予告

次回はページとレイアウトについて解説します。

Inertia.js入門記事一覧
Inertia.jsでシンプルにSPAを構築する Inertia入門#1
Inertia.jsを使うとLaravelやRubyonRailsなどのフレームワーク上でAjax用のAPIやコントローラーを作成しなくても、通常のビューを使う要領でSPA(シングルページアプリケーション)が構築できます。
Laravel 10+Inertia.js+Tailwindインストール Inertia入門#2
この記事ではLaravelにInertia.jsをインストールしてHelloWorldを出力する方法までを解説します。
Inertia.jsのルーティングとレスポンス作成 Inertia入門#3
Laravel8でjetstreamを入れるとLimewireかInertiaかを選べます。この記事ではInertiaを使ってルーティングやInertiaレスポンスの返し方を解説します。
Inertia.jsでページレイアウト Inertia入門#4
この記事では、ページレイアウトについて解説します。親レイアウトに子ページを組み込むことで、ヘッダーやフッターを共通化できます。
Inertia Linkの使い方 Inertia.js入門 #5
この記事では、Inertia.jsのLinkコンポーネントについて解説します。
Inertia.jsでXHRリクエスト Inertia.js入門 #6
この記事では、Inertia.jsで非同期通信を行うrouter.visit()について解説します。
Inertia.jsでのフォームとリダイレクト Inertia.js入門 #7
この記事では、Inertia.jsでのフォーム送信とリダイレクトについて解説します。
Inertiaでのバリデーション Inertia.js入門 #8
この記事では、Inertia.jsを使った際のバリデーションエラーの表示について解説します。
Inertiaで共通データとフラッシュメッセージ Inertia.js入門 #9
この記事では、Inertiaのレスポンスに毎回同じデータを含める方法やフラッシュメッセージの使い方について解説します。
この記事を書いた人

PHPが好物な個人開発プログラマ。フリーランスエンジニアとしてWebサービス作ったりしてます。15年の経験を生かしてMENTAでメンターもやってます。WordPressやPHPでお困りのことがあればご相談に乗りますのでDMください。

Follow on SNS
Laravel
SOHO MIND

Comments

タイトルとURLをコピーしました