理系公務員のプログラミング日記

【Laravel9×Vue3】本の貸し出しシステム6(本の個別ページ)

タグ:
Laravel
Vue

VueRouter の動的ルーティングを利用して、本の個別ページを作る

本を選ぶときに、タイトルだけでなくその本の情報をじっくり確認できる方が好ましいです。

この本を借りることを個別ページで選択できるといいなと思います。

BookList のコンポーネントで表示される本のタイトルからリンクを作り、本の個別ページに移動できるようにします。

動的ルーティングについて

本の各ページを個別で作るとキリがありません。同じレイアウトが書かれたコンポーネントを作成し、そこに本のデータを投入するものとします。

そのために vuerouter の動的ルーティングを利用します。

動的ルーティングを利用すると、各本の個別ページのパスを

path: '/book/:id';

と書くことで、/book/1 や /book/2 のようなパスを作ることができます。

とりあえず個別ページをこんな感じに書いてみます。

components/BookDetail.vue

<template> <h2>書籍の詳細</h2> <div> <!-- 本の情報を受け取って表示させる --> </div> </template> <script> export default { name: 'BookDetail', }; </script>

これを vuerouter で呼び出します。

router/index.js

{ path: '/book/:id', name: 'book', component: BookDetail, },

このページに対して、BookList.vue から移動できるように設定します。

BookList.vue

template 部分のみ

<template> <!-- 中略 --> <ul v-for="Book in Books" class="list-group"> <router-link v-bind:to="{ name: 'book', params: { id: Book.book_id }}"> <li class="list-group-item">{{ Book.title }}</li> </router-link> </ul> </template>

これで BookList.vue からアクセスできること確認したら、BookDetail.vue から、API に対してリクエストを投げます。

この API の当て先について、/api/books/{book}というルーティングが既に作成されているので、それを対象にします。

参考:Laravel 側のルーティングの確認

php artisan route:list
<!-- 中略 -->
  GET|HEAD        api/books/{book} ......................................... books.show › BookController@show
  PUT|PATCH       api/books/{book} ..................................... books.update › BookController@update
  DELETE          api/books/{book} ................................... books.destroy › BookController@destroy

この/api/books/{book}は、/api/books/1 や /api/books/3 のように book_id をパスの中で指定すると、book_id の値が入った変数をコントローラのアクション内で利用できる仕組みです。

まずは、vue 側でルーターオブジェクト$routeから、自身に渡された id を取得して、そこから api のパスを作成します。

BookDetail.vue

<template> <h2>書籍の詳細</h2> <div>{{ bookData }}</div> </template> <script> import axios from 'axios'; export default { name: 'BookDetail', data() { return { bookData: {}, }; }, async mounted() { const url = `api/books/${this.$route.params.id}`; const response = await axios.get(url); this.bookData = response.data; }, }; </script>

その後で、BookController側ではモデルが持つfind()メソッドを利用して、データベースから本1冊の情報を取得します。

BookController.php

public function show($id) { $book = Book::find($id); return $book; }

これによって、本の詳細ページのデータを取得することができました。