【参考】
ステート | Vuex
【初心者向け】状態管理にVuexを使ってみた【入門】 - Qiita
・moduleについて
Vuex の使い方を勉強してみた - Qiita
・mapState
vuexをまだ理解していない全人類に捧ぐvuexを利用したコードの図解 - Qiita
【基本】
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()] //追記 })