【Vue + vue-cli】Vuex – Vueの状態管理ライブラリ
目次
今回はVueの状態管理ライブラリであるVuexについて解説と使い方をまとめていきたいと思います。
なお、今回使うデータに関して、以下の記事のデータを使います。
https://www.dailyupblog.com/web_development/742/
※vue-cliを使っています。
それではいきましょう。
Vuexとは?
Vuexとは各コンポーネントにそれぞれデータを持たせるのではなく、データを1つに集約して、見通しをよくしてくれる状態管理ライブラリです。
コンポーネントの数と扱うデータの数が増えると、データが散らかってしまい、管理しにくくなってしまいます。
それを解消するのが、このVuexです。
下記記事にわかりやすいVuexの図解が載っていたので、ぜひ参考にしてください。
https://qiita.com/m_mitsuhide/items/f16d988ec491b7800ace
Storeについて
StoreとはVuexにおけるデータを集約するコンテナです。
Store内には「state」「mutations」「actions」「getters」を定義します。
それぞれの説明は以下の通りです。
- state・・・data()のようなデータの名前と値を定義し、保持するところ
- mutations・・・stateに保持しているデータに変更を加えたい場合に記述するところ
- actions・・・API通信やstateに保持しているデータに非同期処理を施す場合に記述するところ
- getters・・・computed()と同じような算出プロパティを記述するところ
vuexの実装例
それでは早速Storeで定義される4つの概念である「state」「mutations」「actions」「getters」を実装例を使って解説していきます。
vuexの導入
まずvuexを使えるようにするためにvuexのインストールから行います。
プロジェクトフォルダに移動して、下記コマンドを実行してください。
//npmの場合
npm install vuex
//yarnの場合
yarn add vuex
インストールが完了したら、main.jsファイル内に下記を記述してvuexを利用できる設定をしてください。
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from "vue";
import Vuex from "vuex";
import App from "./App";
import router from "./router";
import store from "./store";
Vue.config.productionTip = false;
Vue.use(Vuex);
/* eslint-disable no-new */
new Vue({
el: "#app",
router,
store,
components: { App },
template: "<App/>"
});
「src」フォルダ直下に「store」フォルダを作成してください。
vuexに関する記述は下記です。
import Vuex from "vuex"; //vuexをインポート
Vue.use(Vuex); //vuexの呼び出し
store, //vuexのstoreを追加
その後、「src」フォルダ直下に「store」フォルダを作成してください。
そして、「store」フォルダ内にindex.jsファイルを作成して、下記を記述してください。
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
});
export default store;
これで準備完了です。
次からはStoreにおける4つの概念について触れていきたいと思います。
stateについて
まずはstateについてです。
stateはStoreにおけるデータの保管場所です。
コンポーネント内で扱われるdata()オプションと同じです。
以下が実装例です。
まず、「store」フォルダ内のindex.jsを開いて、下記を記述してください。
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
str: "Hellow World"
}
});
export default store;
上記のようにデータを定義して、Store内に保持します。
コンポーネント内でstateのデータを参照するには以下のように記述します。
Top.vueを開いて、下記のように記述してください。
<template>
<main>
<div>
<p>{{$store.state.str}}</p>
</div>
</main>
</template>
<script>
export default {
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
p {
font-size: 34px;
font-weight: bold;
}
h2 {
margin: 0;
}
</style>
上記のように「$store.state.データ名」で直接参照することが可能です。
これでページを確認すると「Hello Wrold」が表示されると思います。
mutationsについて
mutationsはstateのデータを更新する時に使います。
mutations内にstateのデータに変更を加える関数を記述します。
mutasions以外でデータを更新することはできません。
以下が使用例です。
「store」フォルダのindex.jsに下記のように記述します。
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
addCount: function(state) {
state.count++;
},
subtractCount: function(state) {
state.count--;
}
}
});
export default store;
上記のようにmutationsの中に二つ関数を書きました。
state内のcountに1を足す関数を、1を引く関数です。
その次にTop.vueに下記のように記述してください。
<template>
<main>
<div>
<p>{{$store.state.count}}</p>
<button @click="addCount()">1足す</button>
<button @click="subtractCount()">1足す</button>
</div>
</main>
</template>
<script>
export default {
methods: {
addCount: function () {
this.$store.commit("addCount");
},
subtractCount: function () {
this.$store.commit("subtractCount");
}
}
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
p {
font-size: 34px;
font-weight: bold;
}
h2 {
margin: 0;
}
</style>
methodsの中にStore内で定義したmutationsの関数を呼び出す関数を二つ記述しています。
上記のようにmutationsの関数をコンポーネント内で参照する場合は「$store.commit(“関数名”)」で呼び出します。
今回は関数の中でmutationsを参照しているため、「this.」が必要です。
そして、これをクリックイベントで関数発火を設定して、pタグ内に「{{ $store.state.count }}」と記述すれば、ボタンの押下で、数値の足し引きができると思います。
actions
actionsはStore内でAPI通信や非同期処理を定義する際に使います。
mutationsの処理を実行する場合などにも記述します。
以下、mutationsの処理をタイマー処理で非同期処理的に発火させる例です。
「store」フォルダのindex.js内に以下のように記述します。
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
addCount: function(state) {
state.count++;
},
subtractCount: function(state) {
state.count--;
}
},
actions: {
timerCount: function({ commit }) {
setInterval(function() {
commit("addCount");
}, 1000);
}
}
});
export default store;
上記のようにactions内に関数を記述します。
「{commit}」を引数に持たせて、さらにsetIntervalを使って非同期処理的にaddCountを呼び出すように書きました。
その後、Top.vueには以下のように記述してください。
<template>
<main>
<div>
<p>{{$store.state.count}}</p>
<button @click="addCount()">1足す</button>
<button @click="subtractCount()">1足す</button>
<button @click="timerCount()">タイマースタート</button>
</div>
</main>
</template>
<script>
export default {
methods: {
addCount: function () {
this.$store.commit("addCount");
},
subtractCount: function () {
this.$store.commit("subtractCount");
},
timerCount: function () {
this.$store.dispatch("timerCount");
}
}
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
p {
font-size: 34px;
font-weight: bold;
}
h2 {
margin: 0;
}
</style>
新たにmethods内にtimerCount関数を記述し、actionsで定義した関数を参照しています。
イベント処理で、ボタン押下でこの関数を発火させると、数値が1秒ごとに足されていくタイマーになります。
gettersについて
gettersはStore内で、computed()と同じような算出プロパティを記述する場合に使います。
以前の記事でcomputedで使った例をgettersで書いてみましょう。
「store」フォルダのindex.jsを開いて、下記のように記述してください。
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0
},
getters: {
double: function(state) {
return state.count * 2;
}
}
});
export default store;
上記のように記述してください。
gettersの中に算出プロパティ的にstateのcountに2をかけた数値を返す処理の関数を記述します。
その後Top.vueに下記のように記述してください。
<template>
<main>
<div>
<input type="number" v-model="$store.state.count" />
× 2 = {{ $store.getters.double }}
</div>
</main>
</template>
<script>
export default {
}
</script>
<style scoped>
main {
height: calc(100vh - 152px);
padding: 3% 0;
box-sizing: border-box;
display: flex;
justify-content: center;
align-items: center;
}
p {
font-size: 34px;
font-weight: bold;
}
h2 {
margin: 0;
}
</style>
computedの時の例と同じですが、v-modelを使ってデータバインディングを行います。
この際、「v-model=”$store.state.count”」とstoreのデータを参照しています。
計算結果には「$store.getters.double」と記述することで、storeのgettersの処理を参照して、返ってきた計算結果を表示させるようにします。
このようにgettersを参照する場合は「$store.getters.関数名」と記述します。
このようにcomputedの時と同じ、入力されている数値を変更するとリアルタイムで計算結果が更新される例をstoreで実装できます。
まとめ
今回はvuexの概要説明と使い方についてまとめました。
アプリケーション開発などで、データを集約させるのに必須のライブラリなので、積極的に活用していきたいところです。
vuexを駆使して、みやすいプログラムをかけるようになりましょう!
筆者も頑張ります!
それでは今回はここまで
お疲れ様でした!
以下、Vue公式の解説です。
Vuex とは何か?
https://vuex.vuejs.org/ja/
Vuex 入門
https://vuex.vuejs.org/ja/guide/