読者です 読者をやめる 読者になる 読者になる

Motomichi Works Blog

その日学習したことについて書いている日記です。誰かの役に立ったらそれはそれで嬉しいです。

vuex2.xその0004 modulesによるstoreの分割と、mapGetters()でmoduleを跨いだgettersやstateの参照をしやすくする

参考にさせて頂いたページ

はじめに

babelは使用せずに、Chromeで動作確認をしています。 参考ページのmapGetters()のサンプルで、オブジェクトのスプレッド演算子(Spread Operator)が使用されていますが、エラーが出たのでObject.assign()を使用しています。

storeがすごく大きくなったりしないようにとか、機能ごとに分割する方が管理がしやすいだろうということでmodulesとかmapGetters()の使い方を学習しました。

今回のバージョン

  • Vue.js v2.1.10
  • vuex v2.3.0

サンプルソースコード

以下の通りです。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta charset="utf-8">
<title></title>
<meta name="description" content="">
<meta name="author" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/style.css">
<link rel="shortcut icon" href="">
</head>
<body>

<div id="app">
</div>

<script src="js/vue.js"></script>
<script src="js/vuex.js"></script>
<script>
const mapGetters = Vuex.mapGetters;

/**
 * Store
 */
const moduleA = {
  strict: true,
  state: {
    count: 0
  },
  mutations: {
    incrementA: state => state.count++ ,
    decrementA: state => state.count-- ,
  },
  getters: {
    moduleAState: state => state ,
  }
};

const store = new Vuex.Store({
  strict: true,
  modules: {
    a: moduleA,
  },
})

/**
 * RootComponent
 */
const RootComponent = {
  template: `
    <div>
      <div>mapState使用 : {{ moduleAState.count }}</div>
      <div>this.$state.getters.moduleAStateの方 : {{ count }}</div>
      <button @click="increment">+</button>
      <button @click="decrement">-</button>
    </div>
  `,
  methods: {
    increment() {
      this.$store.commit('incrementA')
    },
    decrement() {
      this.$store.commit('decrementA')
    }
  },
  computed: Object.assign(mapGetters([
      'moduleAState',
    ]),
    {
      count() {
        return this.$store.getters.moduleAState.count;
      }
    }
  ),
  created() {
    console.log('this.moduleAState.count : ' + this.moduleAState.count);
  }
};

/**
 * VueModel
 */
const app = new Vue({
  el: '#app',
  store,
  components: { RootComponent },
  template: `
    <div class="app">
      <root-component />
    </div>
  `,
});

</script>

</body>
</html>

modulesとmapGettersを使ってみて個人的要点

  • modulesに分割しても、this.$store.commit('hoge')で全てのコンポーネントから全てのmutationsが呼び出せる
  • actions、gettersについても同様にthis.$store.dispatch('hoge')this.$store.getters.hogeなどで全てのコンポーネントから呼び出せる
  • this.$store.getters.moduleAState.countと記述すると冗長ですが、mapGetters()を使用するとそのコンポーネントのcomputedのgetterとして簡潔な記述で呼び出せるようになる

公式ドキュメントに書いてありますが、グローバルな空間にactionsなどもろもろの名前が定義されるので、どのコンポーネントからでもthis.$storeのプロパティとして呼び出せます。 namespaced: trueを設定すると名前空間を切ることができます。