Vue3 + laravel10でSPA作成　②DB連携

## はじめに
本記事は[Vue3 + laravel10でSPA作成　①環境構築](https://qiita.com/ddtwn/items/b899d80c93ca34caf0f1)の続きになります。
今回の目標はトップページ作成と`axios`を使用したDB連携までとなります。
## トップページ作成
### １．App.vueの編集
`resources\views\App.vue`を作成します。各タグの説明は以下になります。
・`v-app`：このタグの中のみ`Vuetify`が有効になります。
・`topHeader`：ヘッダーを読み込みます。
・`router-view`：URLに応じて`router.js`で定義されたテンプレートが返されます。
```vue:App.vue
<template>
    <v-app>
        <topHeader></topHeader>
        <v-main>
            <router-view></router-view>
        </v-main>
    </v-app>
</template>
<script setup>
import topHeader from "./TopHeader.vue"
</script>
```
### ２．トップヘッダー部品の作成
`resources\views\TopHeader.vue`を作成します。
```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>
```
### ３．トップページの中身を作成
`resources\views\Home.vue`を作成します。
```vue:Home.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>
                        <td>
                            <v-btn @click="moveTodoDetail(item.TODO_ID)" density="compact" class="mx-4"
                                color="green">更新</v-btn>
                            <v-btn @click="deleteTodo" density="compact" color="red">削除</v-btn>
                        </td>
                    </tr>
                </tbody>
            </v-table>
        </div>
        <div class="mt-5">
            <v-row>
                <v-col cols="10"></v-col>
                <v-col cols="1">
                    <v-btn @click="createTodo" color="blue-accent-2">新規作成</v-btn>
                </v-col>
            </v-row>
        </div>
    </v-container>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'

// 一覧取得
const todoList = ref([])
onMounted(async () => {
    var res = await axios.get('getTodoList')
    todoList.value = res.data
})

// 詳細に遷移(更新モード)
const router = useRouter()
const moveTodoDetail = (todoId) => {
    router.push({ name: 'detail', params: { todoId: todoId } })
}

// 詳細に遷移(新規モード)
const createTodo = () => {
    router.push({ name: 'detail' })
}

</script>
```
### ４．ルーティング部品の作成
`resources\js\router.js`を作成します。
```javascript
import { createRouter, createWebHistory } from "vue-router";
import home from "../views/Home.vue"

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

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

export default router
```
### ５．app.jsの編集
手順４で作成したルーディング部品を使用するように`resources\js\app.js`を編集します。
※「：」は前後にあるコードの省略を表しています。
```diff_javascript:app.js
：
import 'vuetify/dist/vuetify.min.css'
+ import router from './router'
：
app.use(vuetify) 
+ app.use(router) 
：
```
### ６．axios部品の作成
`axios`と呼ばれるwebサーバ側とのHttp通信を行うライブラリを使用します。
`resources\js\axios.js`を作成します。
```js
import axios from "axios";

const axiosInstance = axios.create({
    baseURL: 'http://localhost:8000/api/',
    headers: {
        "Content-type": "application/json",
    },
})

export default axiosInstance
```
### ７．bootstrap.jsの編集
`resources\js\bootstrap.js`を編集します。
```diff_javascript
- import axios from 'axios';
+ import axios from './axios';
window.axios = axios;

- window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

```
### ８．api.phpの編集
サーバ側の処理を記述します。
`web.php`と`api.php`どちらも使用できますが、今回は`api.php`を使用します。
`api.php`を使用する場合には、IPアドレスとルーティング識別文字列の間に`/api`が付与されるため、手順６で共通で`/api`を付与してアクセスするよう指定しております。
`routes\api.php`を編集します。
```diff_php:api.php
：
use Illuminate\Support\Facades\Route;
+ use App\Http\Controllers\API\TodoController;
：
+ Route::get('getTodoList',[TodoController::class,'getTodoList']);
：
```
### ９．コントローラの作成
`app\Http\Controllers`にAPIフォルダを作成し、フォルダの中に`TodoController.php`を作成します。
```php:TodoController.php
<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;

class TodoController extends Controller
{
    public function getTodoList() {
        $sql = 'SELECT * FROM TODO_LIST';
        $items = DB::select($sql);
        return $items;
    }
}
```
### １０．設定ファイルの編集
`.env`を編集します。
```diff_ini
- DB_DATABASE=laravel
+ DB_DATABASE=TODO
```
## DB作成
`xampp`の「Admin」ボタンから`phpMyAdmin`を起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410887/fd5108ec-fc3d-95a8-8bf9-709845356f93.png)

データベースを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410887/18e7e39a-c7c3-66be-ae7a-36d8802604f8.png)

テーブル作成を行います。
```sql:TODO_LIST.sql
CREATE TABLE TODO_LIST(
    TODO_ID INT AUTO_INCREMENT ,
    TODO_NAME VARCHAR(100) ,
    STATUS VARCHAR(5),
    CREATE_DATE DATE,
    PRIMARY KEY (TODO_ID));
```
## 動作確認
テーブルに適当なデータを入力し、画面表示時に入力したデータが表示されることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410887/31ec2939-c2b5-dc50-7d03-28781de63005.png)