Programming Journal

学習したことの整理用です。

【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するアクション
        });
    },
  }