Vuex 狀態管理
專題公板模組是應公司『大量產生不同專題內容網頁』的需求而生的專案,用意是讓使用者自由拖拉預先設計好的模組、輸入模組所要呈現的內容,最後自動生成靜態網頁供外部瀏覽。
考慮到模組未來的擴充性,以及前端各模組表單欄位的重複性,我們從最小的、各種不同型態的表單輸入欄位開始製作 Vue 元件——不同的表單欄位組成一篇內容,多篇內容填滿一個模組,最後這些模組再加上一些基本設定,匯出成最終的內容網頁。
因應這樣的設計,我們將整個網頁內容的資料以 JSON 格式儲存,並透過 Vuex 統一管理狀態。各元件對各自對應的 key 值做處理,更改狀態之後,所有元件再同步渲染;這樣的單向資料流相對容易理解,未來即使需要元件間共享某些欄位也容易許多。
安裝 Vuex
使用 vuex 前先透過 npm 或 yarn 安裝:
npm
$ npm install vuex --save
yarn
$ yarn add vuex
使用 Vuex
在 app.js 或 main.js 引入並使用:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
狀態管理流程
Vuex 的狀態管理流程可參考官網這張圖片:
Step1. Dispatch Actions
Vuex 的單向資料流是從 Action 開始的,當前端 Vue 元件要修改 State 時,透過 dispatch()
觸發指定 Action。
store.dispatch('definedAction', data)
而在定義的 Action 中,可以處理各種非同步請求,例如向後端伺服器打 API 獲取資料,得到後再向指定的 Mutaion 發出 Commit 要求修改 State。
注意
Action 中不可修改 State,只能執行修改前的資料獲取跟處理;State 的修改一律在 Mutations 中執行。
Step2. Commit Mutations
當 Action 處理完資料,便可以透過 commit()
修改 State。
store.coommit('definedMutaion', key, value)
在指定的 Mutation 中,更新對應的狀態值。
// ...
mutations: {
definedMutation (state, key, value) {
state[key] = value
}
}
Step3. Get State
前端 Vue 元件可以透過 Getter 取得 State,首先設定 getters
:
getters: {
// ...
definedValue: (state) => {
return state.someValue
}
}
接著在前端元件的 computed
中讀取:
computed: {
definedValue () {
return this.$store.getters.definedValue
}
}
或者透過 mapGetters
這個輔助函式讀取:
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
...mapGetters([
'definedValue',
'anotherGetter',
// ...
])
}
}
當 State 更新之後,前端元件也會重新 Render。
Computed 的雙向綁定
在這個專案中,前端連結 State 的都是表單的輸入欄位,若將 State 直接綁定 v-model
,當使用者輸入時,v-model
會試圖直接修改狀態而報錯。
原因
State 的修改只能在 Mutaion 中進行。
若要將 State 與表單欄位綁定,可參考官網這篇的作法,透過 Computed 的雙向綁定,在取值時透過 get
取值,編輯時透過 set
中發出 commit()
更新 State,再藉由 get
取得更新後的值重新刷新。
<input v-model="message">
// ...
computed: {
message: {
get () {
return this.$store.getters.message
},
set (value) {
this.$store.commit('updateMessage', value)
}
}
}