學習 Vuex 狀態管理模式(中)

延續上個章節,認識 Vuex 核心 state, mutations, getters

Jacy Chu
6 min readJun 21, 2021

📝 回顧第一章節:學習 Vuex 狀態管理模式(上)
搭建好 Vuex 專案環境並加入 Bicycle Rental Shop 檔案
這章節將延續上個章節,介紹 Vuex 核心 state, mutations, getters,手把手實作狀態管理!

📋 目錄

  1. [實作] state 介紹與操作
  2. [實作] mutations 介紹與操作
  3. [實作] getters 介紹與操作
  4. [實作] 練習 & 比對前後區別

[實作] 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 部分程式碼如下:

(非完整 App.vue 檔案)

此時畫面上出現腳踏車數量,以及自訂的規則,然而下方 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 部分程式碼如下:

(非完整 App.vue 檔案)

此時開啟瀏覽器,可以操作+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 部分程式碼如下:

(非完整 App.vue 檔案)

此時開啟瀏覽器,上方提到的問題已解決,不過 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 中加入以下程式碼:

(非完整 index.js 檔案)

App.vue 檔案中 <TotalIncome /> 不需要綁定 component 回傳事件,因為狀態統一由 Vuex 管理,程式碼修改如下:

(非完整 App.vue 檔案)

依循上述步驟,Bicycle Rental Shop 專案已完成 Vuex 狀態管理並可以如期運行👏

由於範例屬於小型專案,沒有錯綜複雜的跨建溝通。然而仔細觀察會發現$emitprops沒有用到,即是 Vuex 狀態管理工具要解決的痛點。

🎉 恭喜完成初階練習,在最後一個章節,將會介紹 actions & modules。

🚪 前往下一章節:學習 Vuex 狀態管理模式(下)

When in doubt, pedal it out! 💬

--

--

Jacy Chu
Jacy Chu

Written by Jacy Chu

Front End Developer | 📍Taipei

No responses yet