【Laravel9×Vue3】本の貸し出しシステム6(本の個別ページ)
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> <!-- 中略 --> <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 の当て先について、
参考: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 側でルーターオブジェクト
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; }
これによって、本の詳細ページのデータを取得することができました。