*Vuex とは
Vue.jsで使うことができる、状態管理をするためのライブラリです。Fluxアーキテクチャと同様の設計思想で作られていて、データの変更といった流れが1方向になる仕組みになっています。
(具体的には、storeでデータを保持して複数コンポーネント間からデータの参照や更新をします。)
単純なアプリケーションでは状態管理をしなくても問題ありませんが、中規模・大規模なSPAアプリケーションを構築する場合はVuexを使うことで状態管理が簡単になります。
*環境
- MacOS
- Vue 2.9.6
- vuex-router-sync 5.0.0
- vuex 3.0.1
*参考
*前回の記事
この記事で書いているコードは、前回やった Vue routerを使ったサンプルアプリケーションの続きから始めています。http://mmtomitomimm.blogspot.com/2018/08/vue-router.html
*Vuexのインストール
下記コマンドを実行してVuexをインストールします。storeのなかでrouterを使えるようにするライブラリも一緒にインストールしておきます。
$ npm i -S vuex vuex-router-sync
*Vuex を使うための設定
main.jsにVuexを使うための設定を追加します。ちなみに私は、Vueのインスタンスにstoreの追加が漏れていたせいでstoreで管理している値が表示できず、原因を探すのに少し時間がかかりました。
<main.js>
import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'
import { routes } from './routes'
import store from './store/store' <-- 追加
import { sync } from 'vuex-router-sync' <-- 追加
Vue.use(VueRouter)
const router = new VueRouter({
routes
})
sync(store, router) <-- 追加
new Vue({
el: '#app',
router,
store, <-- 追加
render: h => h(App)
})
*状態管理をするための実装
Vuexで状態管理をするためのstoreディレクトリを作成します。下記構成でjsファイルとmodulesディレクトリも作成します。
src
└─ store
├── modules
│ └── counter.js
└── store.js
modules内にVuexの状態を変更する処理などを書くのですが、その中身をmain.jsにエクスポートするための設定をstore.jsに記述します。
<store.js>
import Vue from 'vue'
import Vuex from 'vuex'
import counter from './modules/counter'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
counter
}
})
modules内のファイルに、状態管理の変更や参照する処理を書きます。
storeに対してcommitで状態を変更、stateで状態の参照ができます。
<counter.js>
import Vue from 'vue'
const state = {
count: 0
}
const mutations = {
'CHANGE_COUNT' (state) {
state.count = state.count + 1
},
}
const actions = {
plusCount: ({commit}) => {
commit('CHANGE_COUNT')
}
}
const getters = {
currentCount: state => {
return state.count
}
}
export default {
state,
mutations,
actions,
getters
}
-
getter
getterは第1引数にstateを受け取ります。(第2引数は他のgetterを受け取ります。)
-
mutations
mutationsをcommitすることでstoreの状態を変更することができます。
Vuexの状態(state)を第1引数として取得します。イベントに近い概念で、定義したタイプのmutationsがトリガーされたときに、その中の処理が呼ばれるようになっています。commitするときにはタイプを指定する必要があります。
-
actions
mutationsと似ていますが、actionsは状態を変更するのでなく、mutationsをcommitします。また、mutationsとは異なり非同期処理をすることもできます。
actionsを書くときは、引数が必ずcontextになるのですが、ここでは引数分割束縛というのが使われていて、コードが少しシンプルになっています。({ commit }の部分)
*コンポーネントから状態を参照
前回の記事で作成したコンポーネントAのファイルを下記に修正します。this.$store
でコンポーネントからstoreを参照することができます。<A.vue>
<template>
<div>
<button @click="countUp">add count</button>
<div>{{currentCount}}</div>
</div>
</template>
<script>
export default {
computed: {
currentCount() {
return this.$store.getters.currentCount
}
},
methods: {
countUp() {
this.$store.dispatch("plusCount")
}
}
}
</script>
- dispatch
actionsは、dispatchをトリガーとして実行されます。
mutationsは同期的でなければなりませんが、actionsは非同期の操作を行うことができるので、mutationsを直接呼ばずにactionsを実行させています。
非同期なAPIを呼び出したり、複数のmutationsのcommitをすることができます。
*アプリケーションの起動
プロジェクトフォルダの直下で下記コマンドを実行します。$ npm run dev
下記にアクセスすると、ボタンとカウント数が表示されます。
ボタンを押すとカウント数が1ずつ増加します。
http://localhost:8080/#/a
*所感
簡単なアプリケーションを作ったことで、Vuexの仕組みや使い方は理解できたのですが、Vueのv-modelを使った双方向バインディングやcomputedなどで定義した値を変更するときにVuexをどう使ったらいいのか、といった実用的なところまでは理解できていないので、まだ学習が必要だと思っています。設計が複雑にならないよう、Vuexを正しく使えるよう理解を深めていきたいです。
※実装したコードはGitHubにあげておきました。
https://github.com/tominagamaya/vue-app
Sign up here with your email
ConversionConversion EmoticonEmoticon