Programming Journal

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

【Vue.js】【Vuex】雑多なメモ

詰まりに詰まってしまったので、メモを残しておきます。

子から親へデータを渡すとき

まず、Vuexは使わない単純なやり方です。
コンポーネントでタスク名・タスク説明文を入力し、親にデータを渡します。
そして親がAPIでその内容をPOSTします。

※説明に必要な部分だけ抜粋

<template>
    <label for="title">タイトル</label>
    <input type="text" class="form-control" id="title" v-model="task.title">

    <label for="description">説明文</label>
    <textarea  name="説明文" class="form-control" id="description" v-model="task.description"></textarea>

    <button @click="handleCreateTask" class="btn btn-success" data-dismiss="modal">追加</button>
</template>

<script>
export default {
  data() {
    return {
      task: {
        title: '',
        description: ''
      }
    }
  },
  methods: {
    handleCreateTask() {
      this.$emit('create-task', this.task)
    }
  }
}
</script>       

$emitで子→親でデータを渡せる。
引数の渡し方で迷ったけど、第2引数で渡せばOK
これで、親側の@create-task="handleCreateTask"が発火する

<template>
  <TaskCreateModal
    v-if="isVisibleTaskCreateModal"
    @create-task="handleCreateTask"/> //子側から受け取る
</template>

<script>
import TaskCreateModal from '../task/components/TaskCreateModal.vue'

// 略
  methods: {
    handleCreateTask(task) {
      axios.post('tasks', task) //試してないのでもしかしたら動かないかも
    }
  }
</script>

handleCreateTask(task)で子から受け取ったデータ(引数)をapi/tasksPOSTします。
※baseURLを登録しているので、tasksと省略形で記述しています。

やらかしたことメモ

タスクのタイトル、説明文にそれぞれv-model:inputTitle v-model:inputDescription のように命名し、1つずつ渡していました。
オブジェクトとして渡せばよかった。ちなみに、オブジェクトは、ハッシュ、連想配列と呼ばれる場合もあるよう。Rubyと混ざって分からなくなる・・

// 子から渡す
this.$emit('create-task', inputTitle, inputDescription)

// 親が受け取る
handleCreateTask(inputTitle, inputDescription) {
   const tasks = { title: title, description: description }
   axios.post("tasks", tasks)

Vuex

Vuex とは何か? | Vuex
API リファレンス | Vuex
ストアの構成要素を理解するまでに時間がかかりました。

  • stateアプリケーション全体で使用されるデータ/コンポーネントでいうdata

  • getters stateから別の値を算出するために使う。/コンポーネントでいうcomputed

  • mutations stateを更新するために使う。mutationは直接呼び出せないので、store.commit('ミューテーション名')で呼び出す。 第2引数でデータも渡せる

  • actions非同期処理やAPIとの通信を行う。ミューテーション呼び出しはここで行う

Vuex内でAPIを叩くには

コンポーネント側は省略
actionmutationsstateのように順番に更新しています。

import Vue from 'vue'
import Vuex from 'vuex'
import axios from '../plugins/axios'

Vue.use(Vuex)

export default new Vuex.Store({
  // stateはcomponentのdataに相当
  state: {
    tasks: [],
  },

  getters: {
    tasks: state => state.tasks
  },

  // mutationsでstateを更新
  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));
    },
    // コンポーネントから受け取ったデータを引数で受け取り、APIに送信してタスクPOSTする
    createTask({ commit }, task) {
      return axios.post('tasks', task)
        .then(response => {
          commit('addTask', response.data)
        })
    }
  },
})