Vue.jsにVuexを導入して、状態管理を簡単にする
今回はVuexを学びます。
Vuexは簡単にいえば、「コンポーネント間のデータのやり取りを簡単にするもの」です。
いままで、コンポーネント間のデータのやり取りは以下の記事のようにやっていました。
上記の記事の例だと、2つのコンポーネント間での動作なのであまり問題はないですが、より多くのコンポーネントでデータの状態を共有したい時には、スマートな方法とはいえません。
そんな時に使うのが「Vuex」です。
先ほど
「コンポーネント間のデータのやり取りを簡単にするもの」
と書きましたが、実際にはデータのやり取りをしているわけではなく、ある箇所でデータを保持していて、どのコンポーネントからもそのデータを参照・更新できるようにしているという感じです。
次回【モジュール分割】
Vuexのサンプル
Vuexを使ったサンプルを作成しました。
どのコンポーネントからでもデータを参照かつ更新ができることがわかります。
■やりたいこと
vuexの使い方
今回はcdnを利用しています。
<script src="https://unpkg.com/vuex"></script>
storeオブジェクトを作成します。
基本的にはstoreオブジェクトはアプリケーションごとに一つ(単一ステートツリー)です。
今回はサンプルで「message」という名前のデータとそれを更新するためのメソッドを用意しています。
/** * storeオブジェクト * messageを保持 * messageの値を書き換える以下の2つのメソッドも用意 * changeMessage() * resetMessage() */ const store = new Vuex.Store({ state: { message: 'homeMessage' }, mutations: { /** * messageの値を「changeMessage」に変更します。・ */ changeMessage (state) { state.message = 'changeMessage' }, /** * messageの値を「homeMessage」に変更します・。 */ resetMessage (state) { state.message = 'homeMessage' }, } })
最後に、Vueコンポーネントもstoreオブジェクトを入れることで、どのコンポーネントからもstoreオブジェクトの値を参照・更新できるようになります。
var app = new Vue({ el: '#app', router, // storeオブジェクト追加 store, methods : { /** * storeのresetMessageメソッドを実行します。 */ resetMessage : function(){ store.commit('resetMessage') } }, computed: { /** * storeからmessageを取得します。 * 画面表示用 */ getMessage () { return this.$store.state.message } } })
storeオブジェクト内のデータを表示する
storeオブジェクトのデータを参照する方法です。
公式サイトでも書かれているcomputed(算出プロパティ)を使用する方法が最も簡単だと思います。
var app = new Vue({ /** 一部省略 */ computed: { /** * storeからmessageを取得します。 * 画面表示用 */ getMessage () { return this.$store.state.message } } })
computedのgetMessageでmessageを取得しています。
これを画面で表示しています。
<p>{{getMessage}}</p>
storeオブジェクト内のデータを更新する
今回は更新するためのメソッドをstoreオブジェクトに用意して、それを各コンポーネントで呼び出す方法を記載します。
このような方法でなくとも、各コンポーネントで直接書き換えることで更新もできます。
例えば、今回の例でいえば
this.$store.state.message = 'page1Message'
このようにすれば「page1Message」の値に更新されます。
今回の実装は以下のとおりです。
Vue.component('page1', { template: '<div>' + '<p>this is page1</p>' + '<button @click="changeMessage">change</button>' + '<button @click="page1ChangeMessage">page1change</button>' + '</div>', methods: { changeMessage(){ store.commit('changeMessage') }, page1ChangeMessage(){ this.$store.state.message = 'page1Message' } } })
上記の実装では、二つのボタンを用意しました。
①change ・・・ storeオブジェクトのchangeMessageを実行するメソッド
changeMessage(){ store.commit('changeMessage') }
このように
store.commit('実行するメソッド')
とすることで、storeオブジェクトに定義したメソッド使うことができます。
この実装をpage1〜3の各コンポーネントに実装して、それぞれから更新できるようにしました。
②page1ChangeMessage ・・・ storeオブジェクトのmessageを直接更新するメソッド
これは先ほど説明したので割愛します。
まとめ
こんな感じで、各コンポーネントからデータの参照・更新ができるできるのは楽ですね。
特に入れ子が深くなるコンポーネントだと、実装がややこしくなるし、メンテとかも大変です。
ただvuexもここで記載したものだけでは本領発揮とはいきません。
mapStateやモジュールを使うことで、より効率的な開発が可能ですhttps://vuex.vuejs.org/ja/。