本文書ではできるだけシンプルな例を通してVuexの説明を行っていきます。Vuexを使った経験がないという入門者の人また下記の図がわからないという人を対象にしています。Vuexが難しいなと感じている人がいるとすれば用語がこれまでのvue.jsよりも増えていることまた記述方法が長かったり短縮形によって複数の書き方があることが原因だと思います。一度理解してしまえば決して難しいものではないので安心して読み進めてください。

vuex diagram
vuex diagram

Vue3では新たに状態管理のライブラリとしてpiniaが登場しました。Vue3で新しいプロジェクトを作成する場合にはpiniaを利用することが推奨されています。

Vuexとは

Vuexはすべてのコンポーネントでデータを一元管理するための仕組みです。

Vuexはstate management(状態管理)という言葉で説明されているため最初は状態という言葉にこだわらずデータ共有管理という名前で考えたほうがわかりやすいかもしれません。
fukidashi

Vuexがない環境ではコンポーネント間のデータの受け渡しには、propsや$emitによるイベントを利用して行います。しかし、コンポーネント間でのデータ受け渡しが頻繁に行われたり階層が増えてくるとporpsや$emitでのデータ管理が難しくなります。

propsは親コンポーネントから子コンポーネントへデータを渡すのに利用します。$emitは子コンポーネントから子コンポーネントで発生した処理、データを親に通知するために利用します。通知を受け取った親コンポーネントでは子コンポーネントの通知に対応する処理を実行します。
fukidashi

複雑に構成されたコンポーネントでのデータ管理の難しさを解決するための仕組みがVuexです。Vuexという一つの入れ物にデータを入れることでどのコンポーネントからでもVuex内に保持するデータへのアクセスが可能になります。

Vuexでのデータ管理のイメージ
Vuexでのデータ管理のイメージ
冒頭に表示したVuexのダイアグラムを見ると難しいのかなと思いますが上の図にあるようにすべてのコンポーネントからアクセスできる入れ物を用意してデータを管理するだけです。複数のコンポーネントで一つの場所にアクセスするためのルールがVuexのダイアグラムにある流れです。例えばファイルを共有するとだれかが開いていると他の人が開けない、データベースの同じ行を更新しようとしたらロックがかかるなど何かを共有するためにはデータの不整合が起こらないためにルールが必要となります。
fukidashi

vue-cliによるプロジェクトの作成

Vuexを使用する環境を構築するためにvue-cliを利用してプロジェクトを作成します。


$ vue create vue-learning

vue-cliのインストールの詳細は説明しませんが、Manually select featuresでBableとVuexだけ選択してインストールを行います。

vue-cliを使用しない場合は、vueとは別にvuexをインストールする必要があります。npmを使っている場合は、package.jsonファイルの中身を確認してvuexがインストール済みかどうか確認してください。

Vuexの基礎

Vuexを使ってHello Vuex

Vuexを使った場合と使わない場合を比較しながらVuexの説明を行なっていきます。

まず最初にVuexを使用しない従来の方法でHello Vuexを表示させるためにsrcディレクトリのApp.vueファイルに下記を記述します。


<template>
  <div id="app">
    <h1>{{ message }}</h1>
  </div>
</template>

<script>
export default {
  name: 'app',
  data: function(){
    return {
      message : 'Hello Vuex'
    }
  }
}
</script>

vue-learningディレクトリでnpm run serveコマンドを実行後、ブラウザでlocalhost:8080にアクセスします。ブラウザにHello Vuexが表示されればvue.jsが正常に動作しています。

これまでの方法でHello Vue
これまでの方法でHello Vueを表示

つぎにVuexを使用してHello Vuexを表示させます。vue-cliでインストールする際にVuexを選択したので追加設定を行うことなくVuexを使用することができます。storeディレクトリの下にあるindex.jsファイルを開き、stateにmessageを追加します。

index.jsファイルの中にはstate以外にもmutations、actionsがありますがこれはのちほど説明を行います。

Vuexのstateはdataプロパティと同じものだと考えてください。dataプロパティとは異なる点があるとすれば、Vuexのstateにプロパティを追加することですべてのコンポーネントからアクセスが可能となる点です。

dataはコンポーネントファイルの中で定義され、そのコンポーネントでのみ使えるデータを扱う時の名前、stateはVuexでデータを扱う時の名前と覚えてください。
fukidashi

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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  	message: 'Hello Vuex'
  },
  mutations: {
  },
  actions: {
  }
  modules: {
  }
})

すべてのコンポーネントからアクセスできるとはいえApp.vueのtemplateタグの中でこれまでのように{{ message }}とすればアクセスできるものではありません。App.vueからアクセスするためには$store.state.messageと記述する必要があります。

$store.state.messageは少し長いですが、$storeという大きな入れ物の中にさらにstateという入れ物があり、その中にmessageが入っているイメージを持つことができます。


<template>
  <div id="app">
    <h1>{{ $store.state.message }}</h1>
  </div>
</template>

ブラウザでアクセスし下記が表示されれば、Vuexの管理下にあるstateのmessageを使ってHello Vuexを表示することができています。

Vuexを使ってHello Vuex
Vuexを使ってHello Vuex

これまでの方法とVuexを利用した方法でmessageの内容をブラウザ上に表示することができました。ここまでの動作確認ではアクセスするための文字列は長くなりましたがVuexを使うことで発生する混乱は全くないかと思います。

Vuexとこれまでの方法
Vuexとこれまでの方法
上の図が理解できればVuexの80%は理解できたと行っても過言ではありません。Vuexの中の値が取得できたので次に疑問に思うのはどうやって更新するのだろうだと思います。その方法がわかれば100%の理解になります。
fukidashi

Vuexではデータを共有管理しているので、どのコンポーネントからも同じようにアクセスすることができます。

App.vue以外の他のコンポーネントからも同じようにアクセスできるか確認するためにsrc¥componentsディレクトリの中にHelloVuex.vueファイルを作成します。App.vueの子コンポーネントとして利用するためApp.vueファイルでimportを行います。


<template>
  <div id="app">
    <h1>{{ $store.state.message }}</h1>
    <HelloVuex></HelloVuex>
  </div>
</template>

<script>
import HelloVuex from '@/components/HelloVuex.vue'

export default {
  name: 'app',
  data: function(){
  	return {
  		message : 'Hello World'
  	}
  },
   components: {
    HelloVuex
  }
}
</script>

HelloVuex.vueファイルに下記を記述します。Vuexのmessageにアクセスする方法は子コンポーネントでも親コンポーネントでも同じ$store.state.messageです。どこのコンポーネントからもアクセス方法が同じことからもVuexは独立したデータ保管場所であることが理解できます。


<template>
  <h2>{{ $store.state.message }}</h2>
</template>
<script>
export default {
  name: 'HelloVuex'
}
</script>

子コンポーネントからも$store.state.messageにアクセスできるためHello Vuexが2つ表示されます。stateにあるデータがどのコンポーネントからも同じ方法でアクセスすることができることが理解できました。

子コンポーネントでHello Vuex
子コンポーネントでHello Vuex

computedプロパティを利用してアクセス

{{ $store.state.messag }}を使ってVuexの中のstateを表示させることができましたが、templateタグの中で{{{ $store.state.messag }}を{ message }}で表示させるためにcomputedプロパティを利用することができます。


<template>
  <div id="app">
    <h1>{{ message }}</h1>
  </div>
</template>

<script>

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

変更後もブラウザ上にはHello Vuexが表示されたままの状態になります。

Hello Vue
Hello Vue

今後はcomputedプロパティを利用してVuexのstateへのアクセスを行います。stateのアクセス方法にはGettersというものもありますがそれは後ほど説明します。

オブジェクトデータの表示(従来の方法)

Vuexのデータへのアクセス方法の理解をさらに深めるためにVuex管理下のオブジェクトデータへのアクセス方法を確認します。まずは従来の方法で説明を行い、その後Vuexを使った場合の方法を説明します。

ユーザ情報が入ったusersオブジェクトを利用し、ユーザ情報をリスト化するといったシンプルなものです。

従来の方法では、dataにusersオブジェクトを設定後にv-bindを使って子コンポーネントへdataを渡します。


<template>
  <div id="app">
    <UserList v-bind:users="users"></UserList>
  </div>
</template>

<script>

import UserList from './components/UserList.vue'

export default {
  name: 'app',
  data : function(){
  	return {
  		users:[
	  		{name: 'John', email:'john@example.com', age:22},
	  		{name: 'Merry', email: 'merry@facebook.com',age:33},
	  		{name: 'Ken', email: 'ken@amazon.com',age:29}
		  ]
  		}
  	},
  components:{
  	 UserList
	}
  }

</script>

子コンポーネントUserListを作成し、propsを使って渡されたdataを受け取りv-forディレクティブで展開します。UserListコンポーネントはsrc¥componentsの下に作成します。


<template>
  <ul>
  	<li v-for="user in users"  v-bind:key="user.name">{{ user.name }} ({{ user.email }})</li>
  </ul>
</template>

<script>
export default {
  props : {
  	users: Object,
  }
}
</script>

ブラウザには下記のようにユーザ一覧が表示されます。

これまでの方法でユーザ一覧
これまでの方法でユーザ一覧

オブジェクトデータの表示(Vuexを利用)

今度はVuexを利用してみましょう。usersオブジェクトをstore¥index.jsのstateに移動します。


state: {
	  users:[
	    {name: 'John', email:'john@example.com', age:22},
	    {name: 'Merry', email: 'merry@facebook.com',age:33},
	    {name: 'Ken', email: 'ken@amazon.com',age:29}
	  ]
}

usersオブジェクトをVuexに移動させたので、App.vueファイルではusersオブジェクトが必要でなくなったので削除します。またusersオブジェクトがないためv-bindも必要ありません。


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

<script>

import UserList from './components/UserList.vue'

export default {
  name: 'app',
  components:{
  	 UserList
	}
  }
</script>

子コンポーネント側ではpropsではなくcomputedプロパティを使ってVuexのstateのusersにアクセスを行い、その値を元にユーザ一覧を表示することができます。


<template>
  <ul>
  	<li v-for="user in users">{{ user.name }} ({{ user.email }})</li>
  </ul>
</template>

<script>
export default {
  computed :{
  	users : function(){
  		return this.$store.state.users
  	}
  }
}
</script>
compotedプロパティを利用せず、v-forディレクティブ内のusersを$store.state.usersとしても表示される結果は同じになります。
fukidashi

v-bindやpropsの記述がなくなったことからも先程のmessageの例よりもVuexを使う場合と使わない場合の違いが明確になりVuexのデータ管理がこれまでとは異なることが理解できたかと思います。

Gettersの使い方の確認

computedプロパティと同様の働きをするGettersの使用方法を確認します。

まず、computedプロパティを使ってusersのオブジェクトの中からageが30以下のユーザ情報のみ表示させます。


computed:{
	users: function(){
		return this.$store.state.users.filter(user => user.age < 30);
	}
}

ageが30以下の2名のユーザのみ表示されます。

computedプロパティでfilterを使う
computedプロパティでfilterを使う

次にGettersを利用して同じことを実行します。index.jsにgettersを追加し、ユーザリストの中からageが30以下のユーザ情報のみ表示させるコードを記述します。


export default new Vuex.Store({
  state: {
	  users:[
	    {name: 'John', email:'john@example.com', age:22},
	    {name: 'Merry', email: 'merry@facebook.com',age:33},
	    {name: 'Ken', email: 'ken@amazon.com',age:29}
	  ]
  },
  getters: {
  	users : function(state){
  		return state.users.filter(user => user.age < 30);
  	}
  },
})

UserListコンポーネントの中で先ほど実行していた処理を削除し、gettersを使った処理に変更を行います。Gettersにはthis.$store.gettersでアクセスすることができます。


computed:{
	users: function(){
		return this.$store.getters.users;
	}
}

ブラウザで確認するとGettersを利用する前と同じユーザリストが表示されます。

computedプロパティでfilterを使う
gettersを利用してユーザリストを取得

gettersをcomputedプロパティではなく下記のように直接記述しても結果は同じです。


<li v-for="user in $store.getters.users"  v-bind:key="user.name">{{ user.name }} ({{ user.email }})</li>

computedプロパティだと記述したそのコンポーネント内でしか利用できません。他のコンポーネントで同じ処理を行いたい場合は同じコードをコンポーネント毎に記述する必要があります。しかしGettersを利用するとVuexのstoreの中に保存されているので、他のコンポーネントからも同じ方法で利用することができます。

Vuex内にあるデータの更新方法

Vuex管理下のstate(データ)へのアクセス方法とGettersの使い方がわかったので、次はVuexで管理されているstateの更新方法を確認します。データのアクセス方法が理解できたと思うので更新が理解できればVuexの理解度は100%になります。あと少しです。

store¥index.jsの中のstateにcountを追加し、その値を0とします。


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

通常はコンポーネント内のメソッドを使ってデータ更新を行います。Vuexのstateの値もコンポーネントのmethodsに更新用のメソッドを追加し、下記のようにVuexのstateを直接実行するのではと思うかもしれません。Vuexのstateに対して直接更新することは可能ですが直接更新は行ってはいけません。


//コンポーネントのmethods内で下記のように記述してもいい??
this.$store.state.count++

stateの更新を行うためには、mutations(ミューテーション)を使う必要があります。store¥index.jsにcountの数を増やすmutationsを追加します。mutationsの引数にはstateが渡されます。

ここまで長い文章を呼んできてmutationsを含め聞き慣れない新しい名称が出て読みすすめるのをやめたい気持ちになりそうですが使ううちに慣れるものなのでもう少し我慢してください。mutateには”変更する”という意味があり、その名詞形のmutationsが使われています。ミューテーションという言葉を聞いたら何か変更、更新するのだなと考えてください。
fukidashi

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

mutationsの追加が完了したらmutationsの実行方法を知っておく必要があります。mutationsはcommitを使って実行します。

公式のドキュメントにもVuex storeのstateを更新することができる唯一の方法がmutationsをcommitすることだと記載されています。
fukidashi

//下記のように実行できそうだがダメ
this.$store.mutations.increment

// commitを使ってmutationを実行
this.$store.commit('increment')

stateはmutationsを利用して更新することがわかったので、ブラウザ上にボタンを表示させクリックイベントを設定します。そのボタンをクリックするとmutationsのincrementメソッドが実行されcountの数字が1増えるというコードを追加します。コードは下記のようになりApp.vueファイルに記述します。


<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ずつ増えます。

mutationをcommitしてcount更新
mutationをcommitしてcount更新

mutationsはcommitで更新を行うだけではなくstateの状態の変化を追うことができます。それは次で説明を行います。

stateの状態の変化を確認

stateの状態の変化を確認するためにChromeのdevtoolを開いてVuexのアイコンをクリックします。

devtoolでvuexを確認
devtoolでvuexを確認

devtoolを開いたままUPボタンを押すとCountが増えるのと同時に実行したmutationsが増えていくのを確認することができます。このようにmutationsを介してstateの状態(値)の変化を追うことができます。

mutationsの実行履歴
mutationsの実行履歴

stateの状態の変化が見れるだけではなく選択したmutationsまで戻ったり、選択したmutationsまでの処理を削除することもできます。

  • Commit This Mutation
  • Revert This Mutation
  • Time Travel to This State
commit this mutations
commit this mutations
Revert this mutations
Revert this mutations
Time Travel to this mutations
Time Travel to this mutations

payloadでmutationsに値を渡す

commitには値を渡すことができ、その値はpayloadと呼ばれます。先程はclickで1つ値が増えましたが、一度に10増やしたい場合は10をpayloadに設定するとVuexのmutationsに設定した値を渡すことができます。


  methods: {
  	increment : function(){
  		this.$store.commit('increment',10)
  	}

mutation側でもpayloadを取得できるように引数を増やす変更が必要です。


  mutations: {
    increment : function(state, number) {
      state.count = state.count + number
    }
  }

これでボタンを押すと10アップするプログラムに変更できます。

Actionsを使ってstateを更新

Vuexでは通常のvue.jsのmethodsに対応するactions(アクション)が準備されています。actionsもmutationsのようにstateを更新するために使用されるのですが、大きく2つの違いがあります。

  1. actionsはstateを直接変更するのではなくmutationsを経由して(commit)stateを更新する
  2. actionsには非同期の処理を入れることができる

1については先ほど使用したcountの例を使って説明を行います。

countを更新したい場合はmutationsを使って行うことを説明しました。actionsを使う場合は、actionsの中でcommitを使ってmutationsを実行し、mutationsからcountを更新させます。つまりstateの値をactionsで更新する場合は必ずmutationsを経由して行うことになります。

下記がactionsを追加したコードです。actionsの中でcommitの引数にmutationsのメソッドが入っていることがわかります。actionsでは引数にcontextというオブジェクトが渡されます。


mutations: {
	increment : function(state) {		
		state.count++
    }
},
actions: {
	incrementOne: function(context){
		context.commit('increment')
	}
}

contexはstoreインスタンスが持つプロパティ、メソッドを保持するオブジェクトです。context.state.countでcountの値を取得することもできます。

contextはstate, commit以外にもdispatch, gettersメソッドを使うことができます。
fukidashi

actionsの追加が完了したので、App.vueファイルのincrementメソッドを更新します。incrementメソッドからactionsを実行します。mutationsを実行するのはcommitでしたがactionsを実行するためにはdispatchメソッドを使用します。


  methods: {
  	increment : function(){
  		this.$store.dispatch('incrementOne')
  	}
  },

actionsの追加後も先ほどと同様にブラウザ上のボタンをクリックするとcountの数が1ずつ増えます。

mutationをcommitしてcount更新
actionsを追加してcount更新

actionsにはビジネスロジックを記述し、mutationsではstateを更新する処理を記述します。簡単にいうとactionsには複雑な処理を記述しmutationsはある一つのstateに注目しそのstateの変更を行う処理だけの役割を持つものと考えることができます。

コンポーネントのmethodsからcommitを使ってmutationsを実行するのではなくシンプルな処理でもactionsを通してmutationsを実行することが推奨されているようです。またactionsの中では複数のmutationsを実行することも別のactionsを呼ぶことも可能です。

またcontextの中でcommitしか使わないのであればES6のDestructuringを使って下記のように短縮して記述することも可能です。


actions: {
	incrementOne: function({commit}){
		commit('increment')
	}
}

(2)についてですが、actionsには非同期の処理を入れることができるということはmutationsには非同期処理を入れることができないということを意味します。

実際にはmutationsに非同期処理は入れても動作するので、mutationsでは非同期処理を入れないというのが正しい説明です。stateもmutationsを使わず直接更新ができたようにactionsでもstateを直接更新ができないわけではありません。Vuexは複数のコンポーネントから共有されていることもあり、同時に複数からの処理を正確に処理するためには守らなければいけないルールがあると認識しておく必要があります。
fukidashi

Actionsの非同期処理とは

非同期処理というのはaxiosを使ってサーバからデータを取得するような場面で頻繁に使われる処理です。非同期処理のイメージをもってもらうためにsetTimeout関数を使うと下記のような処理になります。3秒後にmutationsのincrementが実行されcount数が1増えます。


mutations: {
	increment : function(state) {		
		state.count++
    }
},
actions: {
	incrementOne: function(context){
	    setTimeout(() => {
	      context.commit('increment')
	    }, 3000)
  
	}
},

axiosを使って非同期でデータを取得

axiosを使って非同期でデータを取得する流れの中でどのようにActionsとMutationsが利用されるのか確認しておきます。これを見るとActionsの中で非同期処理を入れることとMutationsの中に入れないことが理解できると思います。

axiosがインストールされていない場合はnpmコマンドでインストールを行います。


 $ npm install axios

実際にデータを取得したほうが実践的だと思いますので、無料サービスJSONPlaceholderを利用します。https://jsonplaceholder.typicode.com/usersにアクセスするとユーザ一覧を取得することができます。

インストールしたaxiosを利用するためにstore¥index.jsファイルの上部でaxiosのimportを行います。


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

store¥index.jsファイル内のactionsでaxiosを使って非同期でユーザ一覧を取得します。下記の中で非同期処理で取得したデータをcommitでmutationsのsetUsersを実行しています。


actions: {
  getUsers: function({commit}){
    return axios.get('https://jsonplaceholder.typicode.com/users')
        .then(response => {
          commit('setUsers',response.data)
        })
  }
},

mutationsでsetUsersを追加します。setUsersでは非同期処理は行わずただpayloadで受け取ったユーザデータを同期処理でstateのusersに入力しているだけです。


state: {
  users:[],
},
mutations: {
  setUsers : function(state,users) {
    state.users = users
  }
},

store¥index.jsに記述した全体は下記のようになります。


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

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  	users:[],
  },
  mutations: {
    setUsers : function(state,users) {
      state.users = users
    }
  },
  actions: {
    getUsers: function({commit}){
      return axios.get('https://jsonplaceholder.typicode.com/users')
          .then(response => {
            commit('setUsers',response.data)
          })
    }
  },
})

次にApp.vueファイルからdispatchでactionsのgetUsersを実行します。


<template>
  <div id="app">
  	<h1>ユーザ一覧</h1>
    <div v-for="user in users" :key=user.id>
      {{ user.name }}
    </div>
  </div>
</template>

<script>

export default {
  name: 'app',
  computed : {
  	users : function(){
  		return this.$store.state.users
  	}
  },
  mounted(){
    this.$store.dispatch('getUsers')
  }
}
</script>

ブラウザで確認するとユーザ一覧が表示されます。

ユーザ一覧の表示
ユーザ一覧の表示

この動作確認から非同期処理が含まれたActionsとstateの更新処理を同期処理で行うmutationsについて理解することができました。

本文書で動作確認に利用したコード

本文書で最終的に作成したコードは下記の通りです。

App.vueファイル


<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.dispatch('incrementOne');
    }
  },
  computed : {
    count : function(){
      return this.$store.state.count;
    }
  }
}
</script>

store¥index.jsファイル


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++;
    }
  },
  actions: {
    incrementOne: function(context){
      setTimeout(()=>{
        context.commit('increment');
      },3000);
    }
  },
  modules: {
  }
})

まとめ

ここまでの説明を通して下記の図にあるActions, Mutations, Stateの説明をすべて行いました。下記の図が理解できていればVuexの概念はほぼ理解できていると思います。

理解を確認するため、文書の中で度々出てきたcountの例を元に下記の図の流れを追ってみましょう。

  1. ユーザがボタンをクリックするとclickイベントによりローカルメソッドが実行され、そのメソッドの中でdispatchメソッッドが実行されます。
  2. dispatchによりActionsが実行され、Actionsの中のcommitメソッドによりmutationsが実行されます。
  3. mutationsはstateであるcountの値を変更します。
  4. アップされた値は、ブラウザに再描写され、ユーザはアップしたcountの値を確認することができます。
vuex diagram
vuex diagram

ここまでVuexを理解することができましたが、Vuexを使いこなす上で必須ではありませんが本書で触れていないmapState, mapMutations, mapGetters, mapActionsの理解も必要です。下記の文書を参考にしてください。

その他の機能

モジュール化

ここまでの説明ではVuexに保存するstate, mutations, actions, gettersはstore¥index.jsファイルの中に保存していました。アプリケーションが小さい場合はindex.jsファイルだけでVuexの状態を管理することができますがアプリケーションが増えるとコード量も多くなり管理が難しくなってきます。そのためVuexではモジュール化することができます。モジュール化することで機能に応じてファイルを分けることができます。例えばアプリケーションにユーザ認証の機能がある場合はuser.jsファイルという独立したファイルを作成します。機能毎にファイルをわけることでコード管理が楽になります。

storeフォルダの下にmodulesフォルダを作成してuser.jsファイルを作成します。


export const user = {
  namespaced: true,
  state: {
    user: null,
  },
  mutations: {
    setUser(state, payload) {
      state.user = payload;
    },
  },
  actions: {
    login({ commit }) {
    //ログイン処理
    },
    logout({ commit }) {
    //ログアウト処理
    },
  },
  getters:{
  },
};

作成したuserモジュールはstore¥index.jsファイルで下記のように設定することができます。


import Vue from 'vue'
import Vuex from 'vuex'
import { user } from './modules/user';

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    user,
  }
})

アクセスする際は$store.state.user.userとなります。またdispatchによってlogin処理を実行したい場合はdispatch(‘user/login’)となります。namespaced:trueを設定しているためloginではなくuser/loginとなり名前空間を使ってactionsを設定することができます。namespacedを設定していない場合はdispatch(‘login’)となります。