第5回 – Vuex入門 – パート2[getters / modules]

2019.07.08

どうも、むつたくです。
近日リリース予定の弊社アプリケーションで、実際にVue.jsを使用しました。
公開されましたらこのブログにもリンクを貼りますので、是非触れてみてください。

 

SPAライクにしてあり、使用したのはvue-cli3/Vuexになります。
超小規模アプリですが、各コンポーネントで使用する変数が重複していたり、API通信をしているので、
Vuexで一元管理した方が楽だと思い、使用しています。

 

実際使用してみて、やっぱりと言うか、コードや変数の管理がすっごく楽でした。
他にもVue-cliなので、BabelやWebpackも含まれています。クロスブラウザなので必要になります。
(主にIEのため…ですがw

 


 

さて、今回は、Vuexのgettersとmodulesについて紹介して行きます。

参考:公式リファレンス – ゲッター
参考:公式リファレンス – モジュール

まずは、公式を読むに限ります。困った時の公式でもあります。

 

 

(1) getters について

gettersは、Storeの状態を算出するのに使用します。
Vue.jsには各コンポーネントで使用できる算出プロパティ(computed)と言うものがあります。
Vuexでは同じことを実現させるには、gettersを使用します。

 

例えば、Vuexで管理している値を取得するコードが複数コンポーネントで使用している場合、
このgettersに書くことで、あちこちに記載されていた同じコードを纏める事ができます。
store.jsに以下のように記載します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// store.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    hoge: 100
  },
  getters: {
    // アロー関数使用しない場合
    getHoge: function(state) {
      return state.hoge;
    }
    // アロー関数使用する場合
    getHoge: state => state.hoge
  }
});

 

取得する側では、以下のように記載します。

1
2
3
4
5
6
7
8
9
10
11
// index.vue
<template>
  <div id="index">
    <p>ほげ: {{ this.$store.getters.getHoge }}</p>
  </div>
</template>
<script>
export default {
  name: "index"
};
</script>

 

gettersを呼び出しているのは、以下のコードになります。

1
this.$store.getters.getHoge

 

この例では微妙ですが、こうすることで、煩雑だったコードがスッキリします。
また、バグの温床になるかもしれないコードを回避することもできる…かもしれません。

 

getters内で他のgettersを呼び出したい時には、以下のようにします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// store.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    hoge: 100,
    fuga: 250 // ★ここ追加
  },
  getters: {
    getHoge: state => state.hoge,
    HogeFuga: (state, getters) => getters.getHoge + state.fuga // ★ここ追加
  }
});

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// index.vue
<template>
  <div class="home">
    <p>ほげ:{{ this.$store.getters.getHoge }}</p>
    <p>ほげふが: {{ this.$store.getters.HogeFuga }}</p> // ★ここ追加
    <p></p>
  </div>
</template>

<script>
export default {
  name: "home",
};
</script>

store.jsの14行目のように、第一引数にstate、第二引数にgettersを渡すことで、ストアオブジェクトを参照することができます。
一応ですが、この書き方を「プロパティアクセススタイル」と呼びます。

 

ちなみにgettersにも引数を渡すことは可能です。これを「メソッドスタイルアクセス」と言い、
その場合の書き方は、以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// store.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    hoge: 100,
    fuga: 250
  },
  getters: {
    getHoge: state => state.hoge,
    HogeFuga: (state, getters) => getters.getHoge + state.fuga,
    hogePlus: state => (num) => state.hoge + num // ★ここ追加
  }
});

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// index.vue
<template>
  <div class="home">
    <p>ほげ:{{ this.$store.getters.getHoge }}</p>
    <p>ほげふが: {{ this.$store.getters.HogeFuga }}</p>
    <p>ほげプラス: {{ this.$store.getters.hogePlus(330) }}</p> // ★ここ追加
  </div>
</template>

<script>
export default {
  name: "home",
};
</script>

 

キモはstore.jsの15行目ですね。これで、データを加工したくなった場合も、容易に可能になりました。
これはプロパティアクセススタイルではできませんので、注意してください。
ともあれ、getters便利!

 

 

(2)modules について

Vuexはすごく便利なのですが、アプリに対して1つしか使用できないので、コンポーネント側はスッキリ!
でも、Storeの中身は可読性が悪く、ごちゃごちゃ…なんてことになったら、本末転倒ですね。

 

それを解消してくれるのが、modulesになります。よく言われるのがモジュール分割。

 

機能ごとに分割すれば、コードの可読性も良くなりますし、管理もし易いはずです。
プロジェクトに後から参入した方が居たとしても、理解がスムーズになったり、
共同作業が捗ったりするのではないでしょうか。

 

さて、分割の仕方ですが、以下のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// store.js
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

// hogeのモジュール
const moduleA = {
  namespaced: true,
  state: {
    hoge: 100
  },
  getters: {
    getVal: state => state.hoge
  },
  mutations: {
    hoge_mutations: () => {
      // 省略 ...
    }
  },
  actions: {
    hoge_actions: () => {
      // 省略 ...
    }
  }
};

// fugaのモジュール
const moduleB = {
  namespaced: true,
  state: {
    fuga: 250
  },
  getters: {
    getVal: state => state.fuga
  }
};

export default new Vuex.Store({
  modules: {
    modA: moduleA,
    modB: moduleB
  }
)};

 

これで、モジュール分割完了です。
分割に際して、必ずと言って良いほど namespaced: true を設定します。名前空間を与えることにより、影響範囲を限定的にできますし、名前空間を与えないことにより、他のmodulesに登録済みのmutationsやactionsと言ったものが同時に実行されてしまいます。gettersに関しては、エラーが出力されます。
なので、namespaced: true を忘れないようにしましょう。

 

コンポーネント側から呼び出す際も、書き方が若干変わります。

1
2
3
4
5
6
7
8
9
10
11
12
<template>
  <div class="home">
    <p>A : {{ this.$store.getters["modA/getVal"] }}</p>
    <p>B : {{ this.$store.getters["modB/getVal"] }}</p>
  </div>
</template>

<script>
export default {
  name: "home",
};
</script>

 

同じ名前のgetValにアクセスしていますが、3行目はmodAの、4行目はmodBのgetValにアクセスするよ、というようになります。
アクセスの仕方を纏めると、以下のようになります。

 

1
2
3
4
// コンポーネント側からの呼び出し
this.$store.commit("modA/hoge_mutations") // mutationsの呼び出し
this.$store.dispatch("modA/hoge_actions") // actionsの呼び出し
this.$store.getters["modB/getVal"]        // gettersの呼び出し

 

このように、namespaced: true を設定することでモジュールごとのmutations、actions、gettersを呼び出せます。
gettersだけ、[]での呼び出しになっているので、そこだけは注意してください。

 

 


 

今回は、Vuexのgettersとmodulesについて紹介しました。
紹介と言っても基本的なことですが。

以上となります。
….Vue.jsとっても楽しいよ!


Top