Vuexを始める

前から気になっていたVuexを始めました。
Vuexとは
公式サイト(Vuex とは何か? · GitBook)には以下のように書かれている。
Vuex は Vue.js アプリケーションのための 状態管理パターン + ライブラリです。
Fluxを参考に作られているらしいけど、Fluxとはなんだろう?という疑問が出てきた。
Fluxとは
結局FluxやらReduxやらって何なのか個人的なまとめ - Qiitaが分かりやすい。
Facebookが提唱しているアーキテクチャで、JavaScriptのデータの流れを分かりやすく整理するために使われます。
フロントエンド周りはビューが複雑に絡み合い、データがどう動くのか分からなくなることが多い。一つのデータを変更すると、それを参照している複数のビューが表示を変え、そして別のイベントが発火され・・という感じでカオスな状態になるのが目に見える。
データの流れを整理することで、このカオスな状態を整理整頓するということだ。ところで、Fluxの読み方は"フラックス"である。
Vuexの仕組み
Vuexの話に戻ってくるが、Vuexの仕組みは以下の通り。

Actionの役割は、データを取ってきたり、計算を行う(非同期処理が可能)。Mutationの役割は、Stateの状態を変更する。Stateの役割はデータを保持すること。コンポーネントはStateのデータを表示し、ユーザ操作があればActionを呼び出す。
シンプルで簡単だな、という印象。
Vuexを始める
vue-cliを使ってプロジェクトを作成し、vuexをセットアップする。
プロジェクト作成
vue-cliを使うと、コマンドで一発である。
npm install --global vue-cli
vue init webpack todo_vue
  ? Project name todo_vue
  ? Project description todo webapp
  ? Author ei <ei.email.com>
  ? Vue build standalone
  ? Install vue-router? Yes
  ? Use ESLint to lint your code? Yes
  ? Pick an ESLint preset Standard
  ? Setup unit tests with Karma + Mocha? Yes
  ? Setup e2e tests with Nightwatch? Yes
cd todo_vue
npm install
以下のファイルが作成された。
todo_vue at a205fa61ac5ae1ece8142f8a7daa52d154317e4f
vuexのセットアップ
npmコマンドでvuexをセットアップ。
npm install --save vuex
バージョンは2.3.1がインストールされた。
Vuexで作るファイル
アプリケーションの構造 · GitBookを参考にし、以下のファイルを作成する。
- store/index.js
 - store/actions.js
 - store/getters.js
 - store/mutation-types.js
 - store/modules/todo.js
 
Vuexを使ったTODOアプリ
vuex/examples/shopping-cartが参考になる。難しいことはせずに、TODOの一覧が出るところまでを作ることにした。
src/main.js
storeを使えるようにする。
main.js at 3e7b05975a9ff171977ba908c02a05e2a8e20bbc
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,
  router,
  template: '<App/>',
  components: { App }
})
/src/store/modules/todo.js
ここがメインの処理。
stateに保持したいデータを保持。gettersで出力の管理。actionsからmutationsを呼び出すときは、commitを使ってやりとりする。actionsとmutationsの書き方は覚える!
todo.js at 3e7b05975a9ff171977ba908c02a05e2a8e20bbc
import * as types from '../mutation-types'
// initial state
const state = {
  all: ['todoA', 'todoB', 'todoC']
}
// getters
const getters = {
  allTodos: state => state.all
}
// actions
const actions = {
  getAllTodos ({commit}) {
    commit(types.RECEIVE_TODOS, {todos: ['todo1', 'todo2', 'todo3']})
  }
}
// mutations
const mutations = {
  [types.RECEIVE_TODOS] (state, {todos}) {
    state.all = todos
  }
}
export default {
  state,
  getters,
  actions,
  mutations
}
/src/store/mutation-types.js
上のtodo.js内でタイプを使っているところの定義。
mutation-types.js at 3e7b05975a9ff171977ba908c02a05e2a8e20bbc
export const RECEIVE_TODOS = 'RECEIVE_TODOS'
コンポーネント
コンポーネントからtodo.jsのgetterを呼び出し、TODOを表示する。また、コンポーネント作成時に、Actionを呼び出して、TODOの値を変更している(APIで取得する代わり)。
Top.vue at 3e7b05975a9ff171977ba908c02a05e2a8e20bbc
import { mapGetters, mapActions } from 'vuex'
export default {
  name: 'top',
  methods: {
    ...mapActions([
    ]),
    goNewTask: function () {
      this.$router.push('Hello')
    }
  },
  computed: mapGetters({
    todos: 'allTodos'
  }),
  created () {
    this.$store.dispatch('getAllTodos')
  }
}
終わりに
簡単にVuexは取り入れることができる。今回のtodo.jsが、エンティティクラスのような扱いで、ここで集中管理していくことになる。小規模なアプリだと少しめんどくさいけど、Vuexを使っておく方が良いと思う。
一部、書き方を覚えないといけないところがあるが、サンプルを参考にしながら一回書けば、次からは難なく書けるだろう。
以下のページが参考になった。
Vue.js + Vuexで開発をしてみよう! - Tech Blog - Recruit Lifestyle Engineer
構造の複雑さとVuex書き分け - Qiita