最近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件のコメント