フロントでVueを使用した表示例

## はじめに
バックエンドにLaravel、フロントにVueを使用して、Vueでデータを表示させるところを行う。
前回、データ作成、jsonでの表示まで行なっており、せっかくなのでVueを使った表示まで記載しておく。
データ作成、およびデータ取得確認は以下で行なっているので、表示箇所のところを記載する。

https://qiita.com/kenji123/items/30639b40f5c7b5a0b373

## Vueで表示する手順

### 手順
データをVueコンポーネントで表示するために、以下のステップを行う。

1. Laravelでjsonデータで返す。
ちなみにLaravelではEloquentモデルの場合は取得したデータを直接返せばよい。
   

2. VueでAPIからデータを取得するメソッドの定義: APIからデータを取得するためには、非同期通信を行いたいので、それを適切に処理するためのコードが必要。
今回はaxiosを使用する。

3. データをコンポーネントの状態に保持する: 取得したデータをコンポーネントの状態に保存する必要がある。Vue3で対応するので、Composition APIを使用してこれを行う。

4. データを表示する: 保存された状態からデータを取得して表示する。

なお、今回では/user/:idで、このパラメータidをプロップとしてコンポーネントに渡す必要がある。これをルーターでおこなう。

### 実装
・router.js
router.jsで以下追加
引数idを取得、UserView.vueを作成する。
```resources/js/router.js
・・・
import UserView from "../views/UserView.vue";

const routes = [
・・
・・
{
    path: "/user/:id",
    component: UserView,
    name: "user",
    props: route => ({ id: route.params.id })
}
]

・・・
```

・UserView.vue
UserView.vueを作成。
デザインはvuetifyを使用している。
CompositionAPIを使用。

```resouces/views/UserView.vue
<template>
    <div v-if="loading">
        Loading...
    </div>
    <div v-else-if="user">

        <v-tabs v-model="activeTab">
            <v-tab value="profile">Profile</v-tab>
            <v-tab value="projects">Projects</v-tab>
        </v-tabs>

        <div v-if="activeTab === 'profile'">
            <!-- Profile content here -->
            <v-card>
                <v-card-title>{{ user.name }}</v-card-title>
                <v-card-text>
                    <p>Email: {{ user.email }}</p>
                    <p>Joined: {{ user.created_at }}</p>
                </v-card-text>
            </v-card>
        </div>
        <div v-if="activeTab === 'projects'">
            <!-- Projects content here -->
            <v-card v-for="project in user.projects" :key="project.id">
                <v-card-title>{{ project.title }}</v-card-title>
                <v-card-text>
                    <p>{{ project.description }}</p>
                    <h4>Tasks:</h4>
                    <ul>
                        <li v-for="task in project.tasks" :key="task.id">
                            {{ task.title }} - {{ task.status }}
                            <ul>
                                <li>{{ task.description }}</li>
                                <li>Due: {{ task.due_date }}</li>
                            </ul>
                        </li>
                    </ul>
                </v-card-text>
            </v-card>
        </div>
    </div>
    <div v-if="error">
        An error occurred: {{ error.message }}
    </div>
</template>

<script>
import { ref } from 'vue';
import axios from 'axios';

export default {
    props: {
        id: {
            type: String,
            required: true
        }
    },
    setup(props) {
        const user = ref(null);
        const loading = ref(true);
        const error = ref(null);
        const activeTab = ref('profile'); // 初期タブを"profile"に設定

        axios.get(`/api/user/${props.id}`)
            .then(response => {
                user.value = response.data;
                loading.value = false;
            })
            .catch(err => {
                error.value = err;
                loading.value = false;
            });

        return {
            user,
            loading,
            error,
            activeTab
        };
    }
}
</script>

```

・バックエンド側
```app/Http/Controllers/ApiController.php
<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class ApiController extends Controller
{
    public function show($id)
    {
        $user = User::with('projects.tasks')->find($id);

        if (!$user) {
            return response()->json(['message' => 'User not found'], 404);
        }

        return $user;
        // return response()->json($user);
    }
}
```
json化はデータをEloquentで取得しているのでしなくてよいが、するのであれば
response()->json($user)でjson化したデータをフロントに渡せる。

以下のように表示される。
・Profile表示
![スクリーンショット 2023-08-14 13.09.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/fd9562ee-1a79-05ae-bcf2-69a89e29986d.png)
・所属するプロジェクト表示
![スクリーンショット 2023-08-14 13.10.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/c7e64100-be58-00cc-1bde-c911ca1ce332.png)



### 主な考慮点
**userデータ表示**
表示においてデータが、表示されない場合がある。
非同期にデータを取得している場合、初期のレンダリングではデータがまだ取得されていない可能性があるため、このようなエラーが発生することがあります。
この問題を解決するためには、今回はテンプレート内でuserオブジェクトが存在するかチェックする。

**タブ切り替え**
表示時のタブの切り替えでタブの詳細表示を、v-tab-itemsで行ったが、
Vuetify3ではVutify2で使用できていたv-tab-itemsは使用できない。
Vuetify3では、タブコンポーネントの仕様が変更されたようである。Vuetify2でのv-tab-itemは、Vuetify3では直接的な置き換えはなさそうであった。
今回は、タブの切り替えには、Vue.jsの通常の制御構造を使用してコンテンツを表示/非表示にした。

## その他
vuetifyのバージョンを確認する。
今回はviteのプラグインを介してvuetifyを使用しているので直接バージョンを確認できない。
以下コマンドで対応した。
```
npm ls vuetify
```
以下のように使用バージョンを把握した。
```
└─┬ vite-plugin-vuetify@1.0.2
  ├─┬ @vuetify/loader-shared@1.7.1
  │ └── vuetify@3.3.11 deduped
  └── vuetify@3.3.11
```