Laravel10でVue3で簡単なSPAを作成する

## はじめに
前回は、環境構築を行なった。
今回はVueよりルーティングを行う、vue router、vuetifyを使用、データをvue内でjsonデータで作って表示まで行う。

## 

## 参考記事

以下の記事の内容をかなり代用し、本記事を作成した。

https://qiita.com/riiiii/items/577a3e3ae28eebf5517c

https://qiita.com/ddtwn/items/b899d80c93ca34caf0f1


### vue routerインストール
```bash
npm install vue-router@4
```
このコマンドは、Vue Router(Vue.jsでのルーティングをサポートするライブラリ)をインストールする。これにより、SPA内でのページ遷移などを実装することができる。

### vuetifyをインストール
```bash
npm install vite-plugin-vuetify
```
このコマンドでVuetify(Vue.jsでのUIコンポーネントライブラリ)をインストールする。

### vite.config.jsを設定
vuetifyを追加
```vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import vuetify from 'vite-plugin-vuetify'←追加

export default defineConfig({
    plugins: [
        vue(),
        vuetify(),←追加
        laravel({
            input: ['resources/css/app.css', 'resources/js/app.js'],
            refresh: true,
        }),
    ],
});
```
ここでは、Viteの設定ファイル(vite.config.js)を編集し、先ほどインストールしたVuetifyをViteプロジェクトで使用できるようにしている。

### app.jsを設定する
resources/js/app.jsを修正する。
vuetify、routerを追加する。

```app.js
import './bootstrap';
import '../css/app.css';
import { createApp } from 'vue';
import App from './App.vue';
import { createVuetify } from 'vuetify';←追加
import router from './router';←追加
import 'vuetify/dist/vuetify.min.css';←追加

const app = createApp(App);
const vuetify = createVuetify();←追加
app.use(router);←追加
app.use(vuetify);←追加
app.mount('#app');
```

### web.phpを修正
localhost:8000以下のURLが何であってもapp.blade.phpを返すようにroutes\web.phpを編集します。
```web.php
<?php

use Illuminate\Support\Facades\Route;

Route::get('/{any?}', fn () => view('app'))->where('any', '.+');
```

app.blade.phpをVueのappに紐づかせている。
```app.blade.html

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel Vite Vue</title>
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>

<body>
    <div id="app"></div>
</body>

</html>
``` 
※前回、welcome.blade.phpを使用していましたが、app.blade.phpに差し替えます。


### ルーティング部品の作成
resources\js\router.jsを作成
```router.js
import { createRouter, createWebHistory } from "vue-router";
import AboutView from "../views/AboutView.vue"
import HomeView from "../views/HomeView.vue"

const routes = [
    {
        path: "/about",
        component: AboutView,
        name: "about"
    },
    {
        path: "/",
        component: HomeView,
        name: "home"
    }
]

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes: routes
})

export default router

```

### App.vueを編集
resources\views\App.vueを以下のように編集する。
※各タグの説明
・v-app：このタグの中のみVuetifyが有効になる。
・TopHeader：ヘッダーを読み込む。
・router-view：URLに応じてrouter.jsで定義されたテンプレートが返される。
```App.vue
<template>
    <v-app>
        <TopHeader></TopHeader>
        <v-main>
            <router-view />
        </v-main>
    </v-app>
</template>

<script>
import TopHeader from "./TopHeader.vue"

export default {
    components: {
        TopHeader
    }
}
</script>

```

### ヘッダー部品作成
resources\views\TopHeader.vueを作成。

```TopHeader.vue
<template>
    <v-app-bar color="blue-grey-lighten-3" density="compact">
        <v-toolbar-title>Todoアプリ</v-toolbar-title>
    </v-app-bar>
</template>
```

### ルーティングのVueを作成
・HomeView.vue
一覧取得表示。
```HomeView.vue
<template>
    <v-container fluid>
        <h4 class="mb-5">ToDo一覧</h4>
        <div class="table-list">
            <v-table density="compact">
                <thead>
                    <tr>
                        <th>No.</th>
                        <th>タイトル</th>
                        <th>ステータス</th>
                        <th>作成日</th>
                        <th></th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(item, index) in todoList" :key="index">
                        <td>{{ index + 1 }}</td>
                        <td>{{ item.TODO_NAME }}</td>
                        <td>{{ item.STATUS }}</td>
                        <td>{{ item.CREATE_DATE }}</td>
                    </tr>
                </tbody>
            </v-table>
        </div>
    </v-container>
</template>

<script setup>
import { ref } from 'vue'

// 一覧取得
const todoList = ref([
    { TODO_NAME: "タスク1", STATUS: "完了", CREATE_DATE: "2023-06-17" },
    { TODO_NAME: "タスク2", STATUS: "未完了", CREATE_DATE: "2023-06-16" },
    { TODO_NAME: "タスク3", STATUS: "完了", CREATE_DATE: "2023-06-15" },
    { TODO_NAME: "タスク4", STATUS: "未完了", CREATE_DATE: "2023-06-14" }
])

</script>
```

・AboutView.php
```AboutView.php
<template>
    <h1>About</h1>
</template>
```


### 画面表示
以上により、下記にアクセスするとルーティングで設定した画面が表示される。

![スクリーンショット 2023-06-17 21.10.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/2d3eb606-6ee4-9801-72d3-df34cd3f8566.png)

![スクリーンショット 2023-06-17 21.10.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176603/7ab113e1-5c1a-1b9a-f802-2be186833bb7.png)