Vuexを使ってみました

*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



Previous
Next Post »

人気の投稿