【Vuex】雑多なメモ
編集時のデータの渡し方
タスク管理アプリで、タスクを編集するときのデータのやり取りについて詰まったのでメモ。
親からtask
データをprops
で受け取り、v-model
でデータを入力値をバインドしたいです。
ただし、オブジェクトが格納された変数をコピーしても、参照がコピーされてしまうため、入力値をバインドすると参照元も変更されてしまいます。
何が起こるかというと、編集を「更新」しなくても、入力フォームに入力した時点でデータが書き換わってしまう。
v-modelじゃなくて:valueにして入力フォームに反映させる??などど1時間ほど詰まってしまってしまいました。
ポイントは、親から子へ渡すデータの時点で、
this.taskEdit = Object.assign({}, task)
などとして、参照ではなく値をコピーして渡します。
assign
メソッドについては、『JS本格入門』P163,165
※説明に必要な部分だけ抜粋
<template> <label for="title">タイトル</label> <input type="text" class="form-control" id="title" v-model="task.title"> <button @click="handleCreateTask" class="btn btn-success" data-dismiss="modal">追加</button> </template> <script> export default { name: 'TaskEditModal', props: { task: { title: { type: String, required: true } } }, methods: { handleUpdateTask() { this.$emit('update-task', this.task) } } } </script>
<template> <TaskEditModal :task="taskEdit" // 子へtaskを渡す v-if="isVisibleTaskEditModal" @close-modal="handleCloseTaskEditModal" @update-task="handleUpdateTask"/> </template> <script> import TaskEditModal from '../task/components/TaskEditModal.vue' export default { components: { TaskEditModal }, data() { return { taskEdit: {}, // 定義しておく。 } }, methods: { handleOpenTaskEditModal(task) { this.isVisibleTaskEditModal = true; this.taskEdit = Object.assign({}, task) // ポイント!子にtaskの値だけを渡す }, async handleUpdateTask(task) { // 説明は略。Vuexのアクションへ飛ばしてAPIでPATCHします try { await this.editTask(task); this.handleCloseTaskEditModal(); } catch (error) { console.log(error); } } } } </script>
VuexでAPIを叩く(PATCH DELETE)
※難しいところだけ抜粋
更新&削除後は、一覧を取得するアクションを呼んでいます。
それだと再び通信することになるので、あまりよくないかもしれないんですが、難しかったのでとりあえず、今回はこれで…
action
内でaction
を呼ぶには…?と悩みましたが、引数にdispatch
を渡して以下の通りにやればOK
mutations: { loadTasks(state, tasks) { state.tasks = tasks }, addTask: (state,task) => { state.tasks.push(task); } }, actions: { // actionでAPIからtask一覧取得 fetchTasks({ commit }) { axios.get("tasks") .then(response => { commit('loadTasks', response.data) }) .catch(error => console.log(error.status)); }, // コンポーネントから受け取ったデータを引数で受け取り、UPDATEする editTask({ dispatch }, task) { return axios.patch(`tasks/${task.id}`, task) .then(response => { dispatch('fetchTasks', response.data) }) }, // コンポーネントから受け取ったデータを引数で受け取り、DELETEする deleteTask({ dispatch },task) { return axios.delete(`tasks/${task.id}`) .then(response => { dispatch('fetchTasks', response.tada) // 一覧をgetするアクション }); }, }