SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

LivewireとInertiaによるLaravelのフロントエンド的画面作成入門

LaravelのInertia+Vueの組み合わせでフロントエンド的な画面を作成する【基本編】

LivewireとInertiaによるLaravelのフロントエンド的画面作成入門 第3回

  • X ポスト
  • このエントリーをはてなブックマークに追加

フロントエンド的な画面の作成方法

 Inertiaの使い方の基本を紹介したところで、次にフロントエンド的な画面の作り方を、図4の画面を使いながら紹介していきます。この画面は、前回の図2と同じ画面です。といっても、実は、前節の基本的なコーディング方法からほとんど差はありません。というのは、画面部分に使っているVueが、そもそもフロントエンド用のフレームワークだからです。具体的にみていきましょう。

図4:カクテルリストと同じ画面内に詳細情報が表示された画面
図4:カクテルリストと同じ画面内に詳細情報が表示された画面

モデルの利用も従来のLaravelプロジェクトと同様

 まずは、コントローラクラスのコードから見ていきます。

 画面に表示するカクテルリストデータというのは、前回同様に、モデルを利用しますが、前節の通りコントローラクラス内でデータを用意するコードというのは、従来のLaravelプロジェクトと差はありません。

 したがって、リスト4のコードとなります。

[リスト4]first-inertia/app/Http/Controllers/CocktailController.php
class CocktailController extends Controller
{
  public function showCocktailList()
  {
    $data["cocktailList"] = Cocktail::all();  // (1)
    return Inertia::render("cocktail/CocktailList", $data);  // (2)
  }
}

 リスト4の(1)でCocktailモデルのall()メソッドにより取得した全カクテルリストデータを、$data連想配列のキーcocktailListとして登録しています。そして、この$dataを第2引数としてInertia::render()メソッドを実行し、その結果をリターンしているのが(2)です。

フロントエンド的な挙動はVueの仕組みを活用

 次に、その(2)の第1引数として指定しているコンポーネントであるcocktail/CocktailList.vueファイルをresources/js/pagesフォルダ内に作成します。これは、リスト5の内容となります。

[リスト5]first-inertia/resources/js/pages/cocktail/CocktailList.vue
<script setup lang="ts">
import {ref} from "vue";
//Cocktailインターフェースを定義。
interface Cocktail {  // (1)
  id: number;  // (1)
  name: string;  // (1)
  price: number;  // (1)
}  // (1)
//Propsインターフェースを定義。
interface Props {  // (2)
  cocktailList: Cocktail[];  // (2)
}  // (2)
//Propsの取得。
const props = defineProps<Props>();  // (3)
//詳細情報セクションの表示非表示切替用変数の用意。
const detailSection = ref(false);  // (4)
//詳細表示セクションに表示するCocktailオブジェクト用変数の用意。
const selectedCocktail = ref<Cocktail|null>(null);  // (5)
//詳細表示セクションを表示させるメソッド。
const showDetail = (id: number) => {  // (6)
  //詳細表示セクションに表示するカクテルデータを取得。
  selectedCocktail.value = props.cocktailList.find(  // (7)
    (cocktailInList: Cocktail) => {  // (7)
      return cocktailInList.id === id;  // (7)
    }  // (7)
  );  // (7)
  //詳細表示セクションを表示に変更。
  detailSection.value = true;  // (8)
};
//詳細表示セクションを非表示にするメソッド。
const closeDetail = () => {  // (9)
  //詳細表示セクションを非表示に変更。
  detailSection.value = false;  // (10)
  //詳細表示セクションに表示するカクテルデータをnullに変更。
  selectedCocktail.value = null;  // (11)
};
</script>

<template>
  <h1>カクテル管理</h1>
  <section>
    <h2>カクテルリスト</h2>
    <ul>
      <li v-for="cocktail in cocktailList" v-bind:key="cocktail.id"><a v-on:click="showDetail(cocktail.id)">{{cocktail.name}}</a></li>  // (12)
    </ul>
    <p>
      <a href="#">カクテルの追加はこちら</a>  // (13)
    </p>
  </section>
  <section v-if="detailSection">  // (14)
    <h2>{{selectedCocktail?.name}}の詳細</h2>  // (15)
    <dl>
      <dt>ID</dt>
      <dd>{{selectedCocktail?.id}}</dd>  // (15)
      <dt>名前</dt>
      <dd>{{selectedCocktail?.name}}</dd>  // (15)
      <dt>金額</dt>
      <dd>{{selectedCocktail?.price}}</dd>  // (15)
    </dl>
    <button v-on:click="closeDetail">閉じる</button>  // (16)
  </section>
</template>

 図4(すなわち、前回の図1、および、図2)の最大の特徴は、リストをクリックすると詳細情報セクションが表示されることです。また、そのセクション内の[閉じる]ボタンをクリックすることで、詳細情報セクションそのものが画面から消えます。

 リスト5で、この処理をどのように実現しているかと言えば、特別なことはなく、(4)で用意したリアクティブな変数detailSectionのtrue/falseを切り替えているだけで、それに連動するように(14)のv-ifが作用し、詳細情報セクションそのものの表示・非表示が切り替わります。この仕組みはLaravelのものではなく、Vueの仕組みそのものです。

 trueへの切り替え処理は(12)のリストの各aタグに設定したv-on:clickのメソッドshowDetail内で行っている(8)が該当します。一方、falseへの切り替え処理は(16)のbuttonタグに設定した同じくv-on:clickのメソッドcloseDetail内で行っている(10)が該当します。

 このように、フロントエンド的な画面挙動は、Inertiaの場合はVueに任せることができます。

モデルに対応したインターフェースを定義

 さて、リスト5の一番肝要な部分を紹介したので、残りのコードに関して軽く補足しておきます。

 カクテルリスト画面に表示するリストデータは、リスト4の(1)でCocktailモデルにより取得したデータベース上のリストデータです。そして、そのリストデータ1件分のデータ項目は、Cocktailモデルオブジェクトそのものであり、もちろん、これはPHPのデータ構造となっています。

 一方、VueなどのフロントエンドはTypeScriptでのコーディングであり、言語が違うので、モデルオブジェクトのデータ構造をそのまま引き継ぐことはできません。

 そこで、Vueの方では別立てでCocktailモデル1件分のデータ構造を定義しておき、それを利用することで、データの不整合を未然に防ぐようにします。それが、リスト5の(1)のCocktailインターフェースです。もちろん、このようなインターフェースは、通常は、各コンポーネント内で定義するのではなく、アプリケーション全体で一元管理します。ここでは説明の関係上、コンポーネントに定義していることをご了承ください。

 このように定義したCocktailインターフェースを利用して、(2)のように、PropsのcocktailList、すなわち、コントローラから渡されるデータの型をCocktailの配列としています。これにより、Laravel(PHP)側のCocktailモデルオブジェクトとVue(TypeScript)側のCocktailオブジェクトが同一データ項目であることが保証されます。

カクテル詳細情報で表示するデータはnullの可能性を考慮

 また、このCocktailインターフェースは、カクテル詳細情報セクションで表示する1件分のカクテル情報であるリスト5の(5)のselectedCocktailでも型指定として利用しています。ただし、カクテル詳細情報セクションが非表示の場合は、データが存在せず、selectedCocktailをnullとする必要があります。

 実際、カクテル詳細情報セクションを閉じる処理メソッドである(9)の内部では(11)でnullを代入しています。そのため、selectedCocktailのデータ型をCocktailとnullのユニオン型としています。それに合わせて、(15)の表示部分では、selectedCocktail?.という記述(オプショナルチェーン)でnullの場合に対応しています。

カクテル詳細情報表示で表示するデータはリストデータから取得

 最後に、そのselectedCocktailを取得しているコードは(7)が該当します。カクテルリストの各カクテル名をクリックしたときの処理メソッドである(6)で、引数として渡されたカクテルのIDを元に、(3)のPropsとして渡されたcocktailListから該当Cocktailオブジェクトを探し出さなければなりません。具体的には(7)のコードが該当し、配列のfind()メソッドを利用し、各要素のidプロパティが引数と合致するものを探し出しています。

 このように、先述のとおり、Inertiaを利用した場合、フロントエンド部分の処理は、すべてVueのコーディングそのものとなります。

 ところで、(13)のカクテル情報追加画面への遷移に関しては、まともなリンクパスが記述されていません。このInertiaを利用したLaravelプロジェクトでの画面遷移に関しては、次回紹介します。

まとめ

 Laravelのフロントエンド的画面作成方法を紹介する連載の第3回目は、いかがでしたでしょうか。

 今回は、InertiaとVueを組み合わせたプロジェクトにおけるコーディングの基礎的な内容を紹介しました。本連載も次回が最後です。その最後として、先述の通り、Inertiaによる画面遷移およびフォームデータの取り扱いを紹介します。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
LivewireとInertiaによるLaravelのフロントエンド的画面作成入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 齊藤 新三(サイトウ シンゾウ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 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本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/21930 2025/07/28 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング