本文書は”入門書必読、vue.jsの状態管理Vuexがわかる”の続きです。主にmapState, mapMutations, mapGetters, mapAcitonsの使い方について説明を行なっています。

本文書を読み前に下記の文書を事前に読むことをおすすめしています。

使用しているコードの確認

ボタンをクリックすることでVuexのstateプロパティであるcountの数字を1だけアップする単純なコードです。vue.jsのプロジェクトで作成していますが、このコード更新を行うのはsrc¥store¥index.jsファイルとApp.vueファイルのみです。


import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  	count: 0
  },
  mutations: {
    increment : function(state) {
      state.count++
    }
  },
})

<template>
  <div id="app">
    <p><button v-on:click="increment">UP</button>
    <h1>Count:{{ count }}</h1>
  </div>
</template>

<script>
export default {
  name: 'app',
  methods: {
    increment : function(){
      this.$store.commit('increment')
    }
  },
  computed : {
    count : function(){
      return this.$store.state.count
    },
  }
}
</script>

ブラウザで確認すると以下の画面が表示され、UPボタンをクリックするとCountの値が1ずつ増えます。

countの初期画面
countの初期画面

mapStateの使い方


App.vueファイルのcomputedプロパティで記述しているthis.$store.state.countは文字数が多いことまた$this.$store.stateまでは共通の文字列なので複数のコンポーネントでthis.$store.state.XXXXを記述したい場合に効率的ではありません。そのためVuexにはmapStateヘルパーという機能が準備されており、mapStateを使うことで短縮して記述することができます。

mapStateだけではなくmapMutations, mapGetters, mapActionsも同じ目的で使用することができます。
fukidashi

mapStateの記述方法

mapStateを利用するためには、vuexからmapStateをimportする必要があります。

mapStateヘルパーを利用して記述したコードが下記となります。


import { mapState } from 'vuex'

export default {
  name: 'app',
  methods: {
    increment : function(){
      this.$store.commit('increment')
    }
  },
  computed: mapState(['count'])
}

mapStateを利用する前と後のcomputedプロパティの記述方法の違いです。記述しても処理する内容は変わりません。記述量が短くなっていることが確認できます。


//mapStateヘルパー利用
computed: mapState(['count'])

//mapStateヘルパーを利用しない場合
computed : {
  count : function(){
    return this.$store.state.count
  }
}

ローカルのcomuptedプロパティとの組み合わせ

computedプロパティをVuexのstateだけに利用する場合はstateプロパティをmapStateの配列に追加(mapState([‘count’,’xxxx’,’yyyy’])することで利用することができます。しかしローカルコンポーネントの独自のcomputedプロパティがある場合は、mapStateにstateが入った配列を使った上記の記述方法は使えないため書き換えが必要になります。

dataプロパティmessageを追加し、messageの文字列をcomputedプロパティを利用して大文字にする処理を追加します。

ローカルのcomputedプロパティとmapStateのcomputedプロパティは、下記のようにSpread Operatorを使うことで設定を行うことができます。


<template>
  <div id="app">
    <p><button v-on:click="increment">UP</button>
    <h1>Count:{{ count }}</h1>
    <h2>{{ upper }}</h2>
  </div>
</template>

<script>¥
import { mapState } from 'vuex'
export default {
  name: 'app',
  data: function(){
    return {
      message: 'Hello Vuex',
    }
  },
  methods: {
    increment : function(){
      this.$store.commit('increment')
    }
  },
  computed : {
    upper: function(){
      return this.message.toUpperCase();
    },
    ...mapState(['count']) //Spread Operatorを利用

  }
}
</script>

mapMutationsの使い方

mapMutationsもmapStateを使い方は同じで、まずimportでmapMutationsを読み込みます。クリックイベントで設定したメソッド名(ボタンのクリックイベントに設定したincrement)とmutationsで設定したメソッド名(increment)が同じである場合のみ利用することができます。設定すると下記のように短縮して記述することができます。


import { mapState,mapMutations } from 'vuex'

export default {
  name: 'app',
  data: function(){
    return {
      message: 'Hello Vuex',
    }
  },
  methods: mapMutations(['increment']), //ここ部分
  computed : {
    upper: function(){
      return this.message.toUpperCase();
    },
    ...mapState(['count'])
  }
}

mapMutationsを利用した場合と利用しなかった場合の記述の違い。


//mapMutationsヘルパー利用
methods: mapMutations(['increment'])

//mapMutationsヘルパーを利用しない場合
  methods: {
    increment : function(){
      this.$store.commit('increment')
    }
  },
ローカルのメソッドがある場合はmapStateと同様にSpread Operator(…mapMutations)を利用します。
fukidashi

mapGettersの使い方

Gettersの追加

mapGettersの使い方を確認する前にGettersの追加を行います。

stateのcountを2倍にするgettersの追加をsrc¥store¥index.jsに追加します。


getters: {
  double: function(state){
    return state.count**2;
  }
},

追加したgettersのdoubleをApp.vueファイルの中に設定します。gettersはcomputedプロパティと同じ働きをするのでcomputedプロパティの中に追加します。


computed : {
  upper: function(){
    return this.message.toUpperCase();
  },
  double: function(){
    return this.$store.getters.double;
  },
  ...mapState(['count'])
}

html側にもdoubleが表示できるように追加を行います。


<template>
  <div id="app">
    <p><button v-on:click="increment">UP</button>
    <h1>Count:{{ count }}</h1>
    <h2>Double Count: {{ double }}</h2>
    <h2>{{ upper }}</h2>
  </div>
</template>

UPボタンをクリックするとDouble CountがCountの2倍になっていることが確認できます。

gettersを追加しcountを2倍表示
gettersを追加しcountを2倍表示

mapGettersの記述方法

mapStateと同様にvuexからimportを行います。computedプロパティは存在するので、Spread Operatorを使ってcomputedプロパティへの追加を行います。


import { mapState,mapMutations,mapGetters } from 'vuex'

export default {
  name: 'app',
  data: function(){
    return {
      message: 'Hello Vuex',
    }
  },
  methods: mapMutations(['increment']),
  computed : {
    upper: function(){
      return this.message.toUpperCase();
    },
    ...mapGetters(['double']),
    ...mapState(['count'])
  }
}
Gettersしかcomputedプロパティに存在しない場合は、mapGetters([‘double’])と記述することができます。
fukidashi

mapActionsの使い方

Actionsの追加

Actionsは設定されていない追加を行います。追加はsrc¥store¥index.jsファイルで行います。

actionsの中ではcommitを使ってmutationsのincrementを実行しています。


actions: {
  increment : function(context){
    context.commit('increment')
  }
}

App.vueのメソッドでactionsのincrementを実行しますが、実行する時はdispatchを使います。先ほどまではincrementメソッドでmutationsのincrementを実行していましたが、ここではactionsのincrementを実行するように変更を行なっています。


<template>
  <div id="app">
    <p><button v-on:click="increment">UP</button>
    <h1>Count:{{ count }}</h1>
    <h2>Double Count: {{ double }}</h2>
    <h2>{{ upper }}</h2>
  </div>
</template>

<script>

import { mapState,mapMutations,mapGetters } from 'vuex'

export default {
  name: 'app',
  data: function(){
    return {
      message: 'Hello Vuex',
    }
  },
  methods:{
    increment: function(){
      this.$store.dispatch('increment');
    }
  },
  computed : {
    upper: function(){
      return this.message.toUpperCase();
    },
    ...mapGetters(['double']),
    ...mapState(['count'])
  }
}
</script>

メソッド名はincrementで変更をしていないので、html側の変更はありません。

mapActionsの使い方

mapStateと同様ににvuexからimportを行います。クリックイベントで設定したメソッド名とactionsで設定したメソッド名が同じである場合のみ利用することができます。


import { mapState,mapMutations,mapGetters,mapActions } from 'vuex'

export default {
  name: 'app',
  data: function(){
    return {
      message: 'Hello Vuex',
    }
  },
  methods: mapActions(['increment']),
  computed : {
    upper: function(){
      return this.message.toUpperCase();
    },
    ...mapGetters(['double']),
    ...mapState(['count'])
  }
}

ローカルコンポーネントのメソッドがないので、mapActions([‘increment’])で記述しています。ローカルコンポーネントのメソッドがある場合は、computedプロパティを参考にSpread Operatorsを利用してください。

非常に簡単な例を使って、mapState, mapMutations, mapGetters, mapAcitonsの説明を行いました。これらのヘルパーは必須ではありませんが、効率的に記述するには役に立つ機能です。

最終的に作成したindex.js, App.vueファイルは以下の通りです。


import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  	count: 0
  },
  mutations: {
    increment : function(state) {
      state.count++
    }
  },
  getters: {
    double: function(state){
      return state.count**2;
    }
  },
  actions: {
    increment : function(context){
      context.commit('increment')
    }
  }
})


<template>
  <div id="app">
    <p><button v-on:click="increment">UP</button>
    <h1>Count:{{ count }}</h1>
    <h2>Double Count: {{ double }}</h2>
    <h2>{{ upper }}</h2>
  </div>
</template>

<script>

import { mapState,mapMutations,mapGetters,mapActions } from 'vuex'

export default {
  name: 'app',
  data: function(){
    return {
      message: 'Hello Vuex',
    }
  },
  methods: mapActions(['increment']),
  computed : {
    upper: function(){
      return this.message.toUpperCase();
    },
    ...mapGetters(['double']),
    ...mapState(['count'])
  }
}
</script>