はじめに
本記事はVue3 + laravel10でSPA作成 ②DB連携の続きになります。
今回の目標は詳細画面の作成とボタンアクションの実装までとなります。
詳細画面作成
1.router.jsの編集
resources\js\router.js
を編集し、詳細画面のルーティングを追加します。
:
+ import detail from "../views/Detail.vue"
const routes = [
{
path: "/",
component: home,
name: "home"
},
+ {
+ path: "/detail",
+ component: detail,
+ name: "detail"
+ },
]
:
2.詳細画面コンポーネントの作成
resources\views\Detail.vue
を作成します。
style scoped
にしていない理由は、Vuetify
が生成するhtml
に対してスタイルを適用したいためです。ただし他コンポーネントまでスタイル適用されるので、注意が必要です。
<template>
<v-container fluid>
<h4 class="mb-5">ToDo詳細</h4>
<div class="input-form">
<v-row>
<v-col cols="2" style="text-align: right; vertical-align: middle;">
タイトル:
</v-col>
<v-col cols="4">
<v-text-field density="compact" hide-details variant="solo"
class="inner-text" v-model="todoDetail.TODO_NAME"></v-text-field>
</v-col>
</v-row>
<v-row>
<v-col cols="2" style="text-align: right;">
ステータス:
</v-col>
<v-col cols="3">
<v-text-field density="compact" hide-details variant="solo"
class="inner-text" v-model="todoDetail.STATUS"></v-text-field>
</v-col>
</v-row>
</div>
<div class="mt-5">
<v-row>
<v-col cols="5">
<v-btn to="/" color="blue-grey-lighten-4">戻る</v-btn>
</v-col>
<v-col cols="2">
<v-btn v-if='props.todoId == null' @click="createTodo" color="blue-accent-2">新規作成</v-btn>
<v-btn v-else @click="updateTodo" color="blue-accent-2">更新</v-btn>
</v-col>
</v-row>
</div>
</v-container>
</template>
<script setup>
import { ref, onMounted } from 'vue'
// 前画面(ホームからToDoIDを受け取る)
const props = defineProps({
todoId: String
})
// ToDoデータ取得
const todoDetail = ref({ TODO_NAME: "", STATUS: "", CREATE_DATE: ""})
if (props.todoId != null) {
onMounted(async () => {
var res = await axios.post('getTodo', props)
if (res.data != undefined) {
todoDetail.value = res.data[0]
}
})
}
// 更新
const updateTodo = async () => {
// ToDo情報にIDを付ける
todoDetail.TODO_ID = props.todoId
await axios.post('updateTodo', todoDetail.value);
}
// 新規作成
const createTodo = async () => {
await axios.post('createTodo', todoDetail.value)
}
</script>
<style>
.input-form {
font-size: 14px;
}
.inner-text input {
padding: 0px 2px 0px 2px;
min-height: 20px;
font-size: 10px !important;
}
</style>
3.詳細画面の画面モード
ホーム画面のボタン押下(「更新」,「新規作成」)によって表示を切り替えます。
「更新」ボタンの場合はtodoId
をパラメータとして送るので、詳細画面がパラメータを受け取れるように、resources\js\router.js
を編集します。
{
- path: "/detail",
+ path: "/detail/:todoId?",
component: detail,
name: "detail",
+ props: true
},
「更新」押下の場合に、更新モードで詳細画面が表示されることを確認します。
4.api.phpの編集
取得、新規作成、更新のルーティングをroutes\api.php
に追加する。
+ Route::post('getTodo',[TodoController::class,'getTodo']);
+ Route::post('updateTodo',[TodoController::class,'updateTodo']);
+ Route::post('createTodo',[TodoController::class,'createTodo']);
+ Route::post('deleteTodo',[TodoController::class,'deleteTodo']);
5.コントローラの編集
+ use Illuminate\Http\Request;
public function getTodoList()
{
$sql = 'SELECT * FROM TODO_LIST';
$items = DB::select($sql);
return $items;
}
+ // 詳細更新モード起動時
+ public function getTodo(Request $req)
+ {
+ $todoId = $req->input('todoId');
+ $sql = 'SELECT * FROM TODO_LIST WHERE TODO_ID = :todoId';
+ $items = DB::select($sql, ['todoId' => $todoId]);
+ return $items;
+ }
+ // 新規作成
+ public function createTodo(Request $req)
+ {
+ $params = $req -> only(['TODO_NAME', 'STATUS']);
+ $sql = <<< 'SQL'
+ INSERT
+ INTO todo_list(TODO_NAME, STATUS, CREATE_DATE)
+ VALUES (:TODO_NAME, :STATUS, CURDATE())
+ SQL;
+ DB::insert($sql, $params);
+ }
+ // 更新
+ public function updateTodo(Request $req)
+ {
+ $params = $req -> only(['TODO_NAME', 'STATUS', 'TODO_ID']);
+ $sql = <<< 'SQL'
+ UPDATE todo_list
+ SET
+ TODO_NAME = :TODO_NAME
+ , STATUS = :STATUS
+ WHERE
+ TODO_ID = :TODO_ID
+ SQL;
+ DB::update($sql, $params);
+ }
+ // 削除
+ public function deleteTodo(Request $req)
+ {
+ $todoId = $req -> input('todoId');
+ $sql = 'DELETE FROM TODO_LIST WHERE TODO_ID = :todoId';
+ DB::delete($sql,['todoId' => $todoId]);
+ }
6.トップページの削除ボタン実装
resources\views\Home.vue
を編集する。
- <v-btn @click="deleteTodo()" density="compact" color="red">削除</v-btn>
+ <v-btn @click="deleteTodo(item.TODO_ID)" density="compact" color="red">削除</v-btn>
:
+ // 削除
+ const deleteTodo = async (todoId) => {
+ await axios.post('deleteTodo', {todoId: todoId})
+ var res = await axios.get('getTodoList')
+ todoList.value = res.data
+ }
確認
新規作成、更新についてはボタンを押下し、戻るを押してトップに戻り、内容が反映されているか確認、削除については押下直後に反映されることを確認する。
さいごに
最後までお読みいただきありがとうございました。
制作時の所感としては、Vuetify2
,Vuetify3
の情報の混在や、laravel10
がまだまだネット記事が充実していないことなどから、環境構築、エラー解消に逐一ハマってしまうことが多かったです汗。
誤りのご指摘、よりよい方法、動作しない等のご意見あればコメントを頂ければと思います。