プログラミンGOO

プログラミングナレッジ、ワードプレス、広告収入等について、気づき・備忘録を残していきます。

Vuex備忘録

【基本】

Vuexではstore>index.tsというファイルの中にstoreで管理した変数・関数を記述する。
主な機能に以下がある

  • state:変数を記述
  • mutations:非同期処理を記述
  • actions:同期処理を記述

■state
・変数を記述する
JavaでいうところのModelにあたる?

■mutations
・同期的(並列処理)な処理を記述する
・mutations内に定義する関数は第一引数にstateを受け取る。
・主にセッターなど、privateな内部処理を記述する
JavaでいうところのLombocがやっている処理に当たる?

mutations: {
  setClientName (state, payload) {
    state.clientName = payload
  }
}

・mutationsの使用

this.$store.commit('funcName', value)

■actions
・非同期(順序制御)な処理を記述する
・戻り値はpormiseになる
JavaでいうところのServiceにあたる?

・actions内に定義する関数は第一引数にcontextを受け取る。
contextとは自分自身。※thisに置き換えても挙動は同じ?
そのためcontextからstateにもアクセスできる

actions: {
  setClientName (context, clientName) {
    context.commit('setClientName', clientName)
  }
}

・actionsの使用

this.$store.dispatch('funcName', value)

■actionsとmutationsの切り分け
actionsはプロミスを返すため、経由することで処理の順序を制御できる(同期処理)
mutationsを直接呼び出すケースはprivate settersに限定すると良いかも

■第3引数が認識されない
mutations、actionsはここまで記述した通り、引数の型が決まっている。
例)mutations(state, payload) //2つまで
複数の引数を渡したい場合は第2引数をオブジェクトとしてまとめて輪つ必要がある

【実装】

~store/index.ts~

state: {
  clientName: null  //…①stateに変数を確保
},
getters: {
  getClientName: (state) => { //…②getterを用意する
    return state.clientName
  }
},
mutations: {
  setClientName: (state, payload) { //…③セッターを用意する
    state.clientName = payload
  }
},
actions: {
  setClientName (context, clientName) {
    context.commit('setClientName', clientName)
      //…③commitでmutationsを呼び出す
      //setterなど情報更新が必要なければactionsだけで完結しても良いかも
  }
},
modules: {
}

~Home.vue~

<form name="myForm">
  <input type="text" name="myText">
  <button @click.prevent="myFunc"></button>
</form>

<script lang="ts">
export default class Home extends Vue {
  //storeから値を取得 ※computedでプロパティを取得する
  get clientName (): string {
    return this.$store.getters.getClientName
  }

  //storeに値を保存
  myFunc () {
    this.$store.dispatch('setClientName', val)  //…④storeのactionsを呼び出す
  }  
}
</script>

【フォーム】form

Vuexで定義した値をv-modelでバインドしようとすると、エラーになる。
これは、値の変更をVuexが検知できなくなるため。
v-modelを分解し、イベント検知とバインド処理を分ける。

~Comp.vue~

<input v-model="clientName">  //エラー

<input v-on:input="setClientName">  //関数を呼び出し、関数内でバインドする

~~~
//ゲッター
get clientName (): string {
  return this.$store.getters.getClientName
}

//セッター
setClientName (e: any) {
  this.$store.dispatch('setClientName', e.target.value) //…②dispatchでactionsを呼び出す
}

~store/index.ts~

state: {
  clientName: null
},
getters: {
  getClientName: (state) => {
    return state.clientName
  }
},
mutations: {
  setClientName (state, payload){
    context.commit('setClientName', clientName) //…③commitでmutationsを呼び出す
  }
},
modules: {
}

【導入】

■vue createでvueプロジェクトを作成する際に、オートではなくマニュアル設定に切り替え、Vuexにチェックを入れる

■後から追加する場合は以下を追記
~main.ts~

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store' //追記

Vue.config.productionTip = false

new Vue({
  router,
  store,  //追記
  render: h => h(App)
}).$mount('#app')

~src/store/index.ts~

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

Vue.use(Vuex)

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

■バージョン確認
node_modules/vuex/README.md
を確認する

fire
**HEADS UP! ** You're currently looking at Vuex 3 branch.

//Vuex 3 であることがわかる

【ローカルストレージにデータを保存】vuex-persistedstate

・リロードしたり、ページ遷移して値が消えるのを防ぐ
・ローカルストレージに情報を保存できるプラグインを使用する。
・ただ、リロード・ページ遷移しても値を使いまわすのはVue本来の使い方ではない気がした。VuehaSPAで値をため込み、一括処理することでサーバとの通信を減らすことができるのが最大のメリット。vuex-persistedstate自体はその域を逸脱してはいないが、『リロード・ページ遷移しても値を使いまわす』という目的自体がSPAでデータをため込む手法の中では特に不整合を起こすリスクをはらむ。あくまで、データを保護する保険的な意味で使用するのがよさそう。

■参考:
【Vuex】リロードしてもStateの中身を消さずに維持する方法 | Pizzamanz.net

■導入

npm install vuex-persistedstate

~store/index.ts~

import createPersistedState from 'vuex-persistedstate'  //追記
export default new Vuex.Store({
  state: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  },
  plubins: [createPersistedState()]  //追記
})