最近nuxt.jsを触っていてvuexについて理解するまでちょっと時間がかかったので、ポイントを整理しておこうかと思います。
nuxt.jsでプロジェクトを作った場合、storeディレクトリがあるので、その下にindex.jsを作ってそこに記述していきます。
今回参考にしたサイトはこちら
コードはこんな感じです。
import _ from 'lodash' // 状態の保存をしておく機能 export const state = () => ({ todos: [] }) // stateから状態を取得する処理 export const getters = { todos_all: state => state.todos, todos: state => state.todos.filter(todo => todo.status === 'todo') } // stateを変更する変更 // 同期的に変更する export const mutations = { addTodo(state, newTodo) { state.todos.push(newTodo) }, } // ビューからのeventに反応してmutationsを発行する処理 // APIとの非同期処理もここで行う export const actions = { async fetchTodos({ commit }) { await this.$axios.$get('/todos').then(res => { let todos = [] if (_.has(res, 'documents')) { todos = res.documents.map(doc => { return { id: _.last(doc.name.split('/')), title: doc.fields.title.stringValue, status: doc.fields.status.stringValue } }) } commit('updateTodos', todos) }) }, async addTodo({ commit }, payload) { const req = { fields: { title: { stringValue: payload.title }, status: { stringValue: 'todo' } } } commit('addTodo', newTodo) } }
ちなみに、上記の方法はモジュールモードで、クラシックモードという以下の書き方もあります。
const store = new Vuex.Store({ state: {}, getters:{}, mutations: {}, actions:{} })
vuexで覚えるべきこと
vuexを使用する上で最初に覚えるべきことはstate、getters、mutations、actions、moduleの5つです。
state
画面に表示するデータを保存しておく機能です。
getters
stateに格納されているデータを取得する機能です。
一覧や詳細ページでデータを表示する際に呼び出されます。
mutations
stateを更新するモジュールのような機能です。
基本的に画面操作では呼び出されず、下のactionsから呼び出します。
ちなみにmutationsを呼び出す場合はcommit(mutation名)という形式になります。
actions
画面操作で呼び出されてAPIと非同期通信したりmutationsを呼び出したりします。
module
moduleは上の4つをまとめる機能です。機能が大きくなった時にストアを分けたい時に使います。
nuxt.jsでmoduleを使いたい場合はstoreディレクトリの下にindex.js以外のjsファイル(例:todos.js)を作成すると自動的にmoduleになるみたいです。
イメージ用のサンプルコードは以下になります。(参照元はこちら)
const moduleA = { state: () => ({ ... }), mutations: { ... }, actions: { ... }, getters: { ... } } const moduleB = { state: () => ({ ... }), mutations: { ... }, actions: { ... } } const store = new Vuex.Store({ modules: { a: moduleA, b: moduleB } })
vuexの使い方
次にvuexを操作する画面を見てみます。
<template> <div> <ul> <li v-for="todo in todos" :key="todo.id"> <span>{{ todo.title }}</span> <small class="change-status" @click="handleDoneTodo(todo)"> done </small> </li> </ul> </div> </template> <script> import { mapGetters, mapActions } from 'vuex' import _ from 'lodash' export default { computed: { ...mapGetters(['todos']) }, methods: { async handleDoneTodo(todo) { const payload = _.cloneDeep(todo) payload.status = 'done' await this.updateTodo(payload) }, ...mapActions(['updateTodo']) } } </script> <style scoped> .change-status { text-decoration: underline; cursor: pointer; text-indent: 1em; } </style>
vuexを使用する際はそのままgettersやactionsを呼び出すのではなく、vuexからmapGettersやmapActionsを使用します。
mapGetters等ヘルパーを使うのは複数のstateやgettersを宣言する際、毎回store.getters.getters名の様に記述するのは冗長なので、省略するために使うようです。
これぐらい理解できていたらひとまずOKでしょう。
0件のコメント