The sky is the limit

ハイブリッドアプリ開発、PWAなど効率の良いiOSアプリ、Androidアプリ開発の情報を共有したい。アプリ開発は楽しい。【PWA、AngularJS、Monaca、Cordova、OnsenUI】

【Vue.js】Vuexを導入して、データの状態変化管理を簡単にする【Vuex】

【Vue.js】Vuexを導入して、データの状態変化管理を簡単にする【Vuex】

f:id:duo-taro100:20160218004611p:plain

今回はVuexを学びます。
Vuexは簡単にいえば、「コンポーネント間のデータのやり取りを簡単にするもの」です。
いままで、コンポーネント間のデータのやり取りは以下の記事のようにやっていました。

www.sky-limit-future.com


上記の記事の例だと、2つのコンポーネント間での動作なのであまり問題はないですが、より多くのコンポーネントでデータの状態を共有したい時には、スマートな方法とはいえません。
そんな時に使うのが「Vuex」です。
先ほど

「コンポーネント間のデータのやり取りを簡単にするもの」

と書きましたが、実際にはデータのやり取りをしているわけではなく、ある箇所でデータを保持していて、どのコンポーネントからもそのデータを参照・更新できるようにしているという感じです。

公式サイト

Introduction · Vuex


Vuexのサンプル

Vuexを使ったサンプルを作成しました。
どのコンポーネントからでもデータを参照かつ更新ができることがわかります。

■やりたいこと

他のコンポーネントからデータを更新したい(より簡単に)


See the Pen how to use vuex by duotaro (@duotaro100) on CodePen.


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/

詳細は公式サイトで。

Introduction · Vuex