學習 Vuex 狀態管理模式(中)
📝 回顧第一章節:學習 Vuex 狀態管理模式(上)
搭建好 Vuex 專案環境並加入 Bicycle Rental Shop 檔案
這章節將延續上個章節,介紹 Vuex 核心 state, mutations, getters,手把手實作狀態管理!
📋 目錄
[實作] state 介紹與操作
state 介紹 📄
Vuex 使用單一狀態樹,一個對象就包含全部的應用層級狀態,且每個應用只包含一個 store 實例。響應式的資料狀態儲存 state , 當資料狀態變化時,有用到的 component 都會即時更新,而數據和 Vue 實例中的data
遵循相同的規則。由於在根實例中已註冊store
,該 store 實例會注入到根組件下的所有子組件中,且子組件能通過this.$store
訪問到。
Hands on 操作 📐
step 1 搬移實例中的 data
將 App.vue 檔案中的 data 搬移至 store/index.js 檔案 state 中。若在此時,查看網頁畫面,會發現有代入 data 的部分會消失。
step 2 加入 $store.state.___
在 App.vue 檔案 template 中有綁定原本data
資料的變數,加上$store.state.___
(底線為原本變數名稱)。此時 App.vue 檔案的 template 部分程式碼如下:
此時畫面上出現腳踏車數量,以及自訂的規則,然而下方 Total Income 部分看起來有問題待解決。
🔖 補充說明
mapState輔助工具:若有許多state,可以使用mapState搭配展開運算符。
e.g. ...mapState(['bicycleNum','rentNum'])即代表下列兩行程式碼:
bicycleNum(){return this.$store.state.bicycleNum}
rentNum(){return this.$store.state.rentNum}
[實作] mutations 介紹與操作
mutations 介紹 📄
若要改變 Vuex,必須提交 mutations。mutations 類似於組件中的事件,接受 state 作為第一個參數,第二個參數(Payload)可以傳入額外參數。調用時以 store.commit
方法呼叫。
Hands on 操作 📐
step 1 搬移實例中的 methods
將 App.vue 檔案中的 methods 搬移至 store/index.js 檔案 mutations 中。function() 傳入 state 參數,並把 function 中所有 this 改成 state。此時 store/index.js 檔案完整程式碼如下:
step 2 加入 $store.commit('funcName')
把原本 @click="funcName"
改成 @click="$store.commit('funcName')"
。此時 App.vue 檔案的 template 部分程式碼如下:
此時開啟瀏覽器,可以操作+1 & -1功能,不過超過 20 或是小於 0,按鍵沒有呈現 disabled 的狀態,這個部分還需要修改一下 🔨
🔖 補充說明
mapMutations輔助工具:若有許多mutations,可以使用mapMutations搭配展開運算符,跟一般mutations一樣可以傳進參數Payload。
e.g. methods:{
...mapMutations(['plusOne'])
}
即代表下方行程式碼:
plusOne(payLoad){
this.$store.commit('plusOne',payLoad)
}
[實作] getters 介紹與操作
getters 介紹 📄
同計算屬性 computed 一樣,getters 返回值會被緩存,只有當它的依賴值發生了改變才會被重新計算。接受 state 作為第一個參數,第二個參數(getter)可以傳入其他 getters。
Hands on 操作 📐
step 1 搬移實例中的 getters
將 App.vue 檔案中的 computed 搬移至 store/index.js 檔案 getters 中。function() 傳入 state 參數,並把 function 中所有 this 改成 state。此時 store/index.js 檔案完整程式碼如下:
step 2 加入 $store.getters.___
在 App.vue 檔案 template 中有綁定原本computed資料的變數,加上$store.getters.___
(底線為原本變數名稱)。此時 App.vue 檔案的 template 部分程式碼如下:
此時開啟瀏覽器,上方提到的問題已解決,不過 Total Income 部分(TotalIncome.vue 檔案)還沒有處理。
🔖 補充說明
mapGetters輔助工具:若有許多getters,可以使用mapGetters搭配展開運算符。
e.g. ...mapGetters(['isdisabledPlusFn','isdisabledMinusFn'])
即代表下方程式碼:
isdisabledPlusFn(){return this.$store.getters.isdisabledPlusFn}
isdisabledMinusFn(){return this.$store.getters.isdisabledMinusFn}
[實作] 練習 & 比對前後區別
💡 請先自行練習處理 TotalIncome.vue 檔案,再參考下方程式碼
完整 TotalIncome.vue 檔案程式碼如下:
store/index.js 會在 getters 中加入以下程式碼:
App.vue 檔案中 <TotalIncome /> 不需要綁定 component 回傳事件,因為狀態統一由 Vuex 管理,程式碼修改如下:
依循上述步驟,Bicycle Rental Shop 專案已完成 Vuex 狀態管理並可以如期運行👏
由於範例屬於小型專案,沒有錯綜複雜的跨建溝通。然而仔細觀察會發現$emit
和 props
沒有用到,即是 Vuex 狀態管理工具要解決的痛點。
🎉 恭喜完成初階練習,在最後一個章節,將會介紹 actions & modules。
🚪 前往下一章節:學習 Vuex 狀態管理模式(下)
When in doubt, pedal it out! 💬