天天看點

Vue3項目實踐-第二篇(狀态管理-Vuex 基礎概念)

作者:繪芽研究社1号
前面丢失了 狀态管理 的 vuex 元件,現在補上。

官網:https://vuex.vuejs.org/

本文将介紹以下内容:

  1. Vuex 是什麼?
  2. 狀态管理模式是什麼?
  3. 快速應用
  4. Vuex核心概念,State:應用程式的狀态資料存儲在單一的狀态樹中。
  5. Vuex核心概念,Mutations:用于修改State的同步函數,必須是純函數。
  6. Vuex核心概念,Actions:處理異步操作,可以包含多個Mutations的調用。
  7. Vuex核心概念,Getters:從State中派生出新的資料,類似于計算屬性。

Vuex 整個内容大綱

Vue3項目實踐-第二篇(狀态管理-Vuex 基礎概念)

會按照以下内容大綱進行更新。

  • Vuex 是什麼?
    • 什麼是"狀态管理模式"?
  • 快速應用
    • 安裝
    • 應用
      • 最簡單的Store
  • Vuex核心概念:
    • State:應用程式的狀态資料存儲在單一的狀态樹中。
    • Mutations:用于修改State的同步函數,必須是純函數。
    • Actions:處理異步操作,可以包含多個Mutations的調用。
    • Getters:從State中派生出新的資料,類似于計算屬性。
  • Vuex的工作流程:
    • 建立Vuex Store:使用Vue提供的createStore函數來建立Vuex Store對象。
    • 注冊Module:通過store.registerModule方法注冊子產品,以子產品化方式組織State、Mutations、Actions和Getters。
    • 在Vue應用中使用Vuex:通過Vue的provide和inject機制,在元件中通路Vuex的State、Mutations、Actions和Getters。
    • 觸發Mutations和Actions:使用commit方法觸發Mutations,使用dispatch方法觸發Actions。
  • 子產品化組織:
    • 在複雜的應用程式中,将State、Mutations、Actions和Getters進行子產品化組織,以便更好地管理群組織代碼。
    • 使用store.registerModule方法注冊子產品,将子產品添加到Vuex Store中。
    • 子產品可以包含自己的State、Mutations、Actions和Getters。
  • 輔助函數:
    • Vuex提供了一些輔助函數,如mapState、mapMutations、mapActions和mapGetters,用于簡化在元件中使用Vuex的代碼。
  • Vuex插件:
    • 學習如何編寫和使用Vuex插件,以擴充Vuex的功能。
    • 插件可以用于記錄日志、持久化狀态、訂閱狀态變化等。
  • 單向資料流和響應式更新:
    • 了解Vuex中的單向資料流,即資料從State流向元件,元件通過Mutations和Actions修改State。
    • 了解Vuex中的響應式更新機制,即當State發生變化時,相關的元件會自動更新。

Vuex 是什麼?

Vuex 是一個專為 Vue.js 應用程式開發的狀态管理模式 + 庫。它采用集中式存儲管理應用的所有元件的狀态,并以相應的規則保證狀态以一種可預測的方式發生變化。

什麼是“狀态管理模式”?

讓我們從一個簡單的 Vue 計數應用開始:

const Counter = {
  // 狀态
  data () {
    return {
      count: 0
    }
  },
  // 視圖
  template: `
    <div>{{ count }}</div>
  `,
  // 操作
  methods: {
    increment () {
      this.count++
    }
  }
}

createApp(Counter).mount('#app')           

這個狀态自管理應用包含以下幾個部分:

  • 狀态,驅動應用的資料源;
  • 視圖,以聲明方式将狀态映射到視圖;
  • 操作,響應在視圖上的使用者輸入導緻的狀态變化。

以下是一個表示“單向資料流”理念的簡單示意:

Vue3項目實踐-第二篇(狀态管理-Vuex 基礎概念)

但是,當我們的應用遇到多個元件共享狀态時,單向資料流的簡潔性很容易被破壞:

  • 多個視圖依賴于同一狀态。
  • 來自不同視圖的行為需要變更同一狀态。

對于問題一,傳參的方法對于多層嵌套的元件将會非常繁瑣,并且對于兄弟元件間的狀态傳遞無能為力。對于問題二,我們經常會采用父子元件直接引用或者通過事件來變更和同步狀态的多份拷貝。以上的這些模式非常脆弱,通常會導緻無法維護的代碼。

是以,我們為什麼不把元件的共享狀态抽取出來,以一個全局單例模式管理呢?在這種模式下,我們的元件樹構成了一個巨大的“視圖”,不管在樹的哪個位置,任何元件都能擷取狀态或者觸發行為!

通過定義和隔離狀态管理中的各種概念并通過強制規則維持視圖和狀态間的獨立性,我們的代碼将會變得更結構化且易維護。

這就是 Vuex 背後的基本思想,借鑒了 Flux、Redux 和 The Elm Architecture]。與其他模式不同的是,Vuex 是專門為 Vue.js 設計的狀态管理庫,以利用 Vue.js 的細粒度資料響應機制來進行高效的狀态更新。

Vue3項目實踐-第二篇(狀态管理-Vuex 基礎概念)

快速應用

安裝

在 Vue 之後引入 vuex 會進行自動安裝:

npm install vuex@next
或
yarn add vuex@next           

應用

每一個 Vuex 應用的核心就是 store(倉庫)。“store”基本上就是一個容器,它包含着你的應用中大部分的狀态 (state)。Vuex 和單純的全局對象有以下兩點不同:

  1. Vuex 的狀态存儲是響應式的。當 Vue 元件從 store 中讀取狀态的時候,若 store 中的狀态發生變化,那麼相應的元件也會相應地得到高效更新。
  2. 你不能直接改變 store 中的狀态。改變 store 中的狀态的唯一途徑就是顯式地送出 (commit) mutation。這樣使得我們可以友善地跟蹤每一個狀态的變化,進而讓我們能夠實作一些工具幫助我們更好地了解我們的應用。

最簡單的 Store

安裝 Vuex 之後,讓我們來建立一個 store。建立過程直截了當——僅需要提供一個初始 state 對象和一些 mutation:

import { createApp } from 'vue'
import { createStore } from 'vuex'

// 建立一個新的 store 執行個體
const store = createStore({
  state () {
    return {
      count: 0
    }
  },
  mutations: {
    increment (state) {
      state.count++
    }
  }
})

const app = createApp({ /* 根元件 */ })

// 将 store 執行個體作為插件安裝
app.use(store)           

現在,你可以通過 store.state 來擷取狀态對象,并通過 store.commit 方法觸發狀态變更:

store.commit('increment')

console.log(store.state.count) // -> 1           

在 Vue 元件中, 可以通過 this.$store 通路store執行個體。現在我們可以從元件的方法送出一個變更:

methods: {
  increment() {
    this.$store.commit('increment')
    console.log(this.$store.state.count)
  }
}           

再次強調,我們通過送出 mutation 的方式,而非直接改變 store.state.count,是因為我們想要更明确地追蹤到狀态的變化。這個簡單的約定能夠讓你的意圖更加明顯,這樣你在閱讀代碼的時候能更容易地解讀應用内部的狀态改變。此外,這樣也讓我們有機會去實作一些能記錄每次狀态改變,儲存狀态快照的調試工具。有了它,我們甚至可以實作如時間穿梭般的調試體驗。

由于 store 中的狀态是響應式的,在元件中調用 store 中的狀态簡單到僅需要在計算屬性中傳回即可。觸發變化也僅僅是在元件的 methods 中送出 mutation。

接下來,我們将會更深入地探讨一些核心概念。

Vuex核心概念

Vue3項目實踐-第二篇(狀态管理-Vuex 基礎概念)

Vuex是Vue.js的官方狀态管理庫,用于管理Vue應用程式的狀态。以下是Vuex的核心概念:

  1. State(狀态):
  2. State是應用程式的中央資料存儲,即存放應用程式中共享的狀态資料。
  3. State通常是一個對象,包含多個屬性,每個屬性代表一個狀态。
  4. State中的資料是響應式的,當State發生變化時,相關元件會自動更新。
  5. Mutations(突變):
  6. Mutations是修改State的唯一方式。
  7. 每個Mutation都是一個函數,用于同步地修改State中的資料。
  8. Mutations應該是純函數,即僅依賴于輸入參數來修改State,不應進行異步操作。
  9. Actions(動作):
  10. Actions用于處理異步操作、封裝業務邏輯,并送出Mutations來修改State。
  11. 每個Action都是一個函數,可以包含異步操作、調用API等。
  12. Action可以通過commit方法來觸發一個或多個Mutations。
  13. Getters(擷取器):
  14. Getters用于從State中派生出新的資料,類似于計算屬性。
  15. Getters可以對State進行包裝、過濾、計算等操作,并傳回派生出的資料。
  16. Getters在元件中類似于計算屬性使用,可以通過this.$store.getters通路。

State(狀态)

State(狀态)是Vuex中的一個核心概念,它代表着應用程式的中央資料存儲。

State存儲着應用程式的共享狀态資料,并且在整個應用程式中可被通路和使用。

以下是State(狀态)的一些關鍵特點和注意事項:

  1. 中央資料存儲: State是一個對象,存儲着應用程式的資料狀态。它可以包含多個屬性,每個屬性代表一個特定的狀态。
  2. 響應式更新: State中的資料是響應式的,這意味着當State的資料發生變化時,使用該資料的元件會自動更新其對應的視圖。
  3. 單一資料源: Vuex鼓勵使用單一資料源的概念,即整個應用程式的狀态集中存儲在一個單一的State對象中。
  4. 通路State: 在Vue元件中,可以通過this.$store.state來通路State的屬性。Vuex通過Vue的響應式系統確定了State的變化能夠被元件實時感覺。
  5. 修改State: State中的資料應該是隻讀的,不應該直接修改State的屬性。要修改State,應該使用Mutations或Actions來觸發狀态的更改。
  6. 避免狀态直接修改: 在Vuex中,應該避免直接修改State中的資料,而是通過送出Mutations或觸發Actions來修改State。這樣可以更好地跟蹤和管理狀态的變化,并提供更好的代碼維護性和可追蹤性。
  7. 子產品化State: 在大型應用程式中,可以使用子產品化的方式來組織State,将其分割成多個子產品,每個子產品都有自己的狀态屬性。

通過合理地使用State,可以更好地組織和管理應用程式的資料狀态。State的設計和使用應該符合單一資料源和響應式更新的原則,并與其他Vuex概念(如Mutations、Actions和Getters)結合使用,以實作可靠的狀态管理和資料流動。

Mutations(突變)

Mutations(突變)是Vuex中用于修改State的唯一方式。Mutations是一個同步函數,用于對State進行同步的變更操作。通過觸發Mutations,可以保證對State的修改是可追蹤的,并且能夠實時更新相關元件的視圖。

以下是Mutations(突變)的一些關鍵特點和注意事項:

  1. 同步變更:Mutations是同步函數,用于進行同步的狀态變更操作。這意味着Mutations中的代碼會立即執行,且在修改完State後,相關元件會立即更新。
  2. 唯一途徑:Mutations是修改State的唯一途徑。這是為了確定State的變更是可追蹤的,并且能夠集中管理對State的修改。
  3. 純函數:Mutations應該是純函數,即僅依賴于輸入參數來修改State,不應進行異步操作或直接觸發其他副作用。這有助于保持Mutations的可預測性和可測試性。
  4. Mutation名稱:每個Mutation都有一個名稱,用于在觸發Mutation時進行辨別。Mutation的名稱通常是一個常量字元串,在Vuex Store中定義。
  5. 調用方式:要觸發Mutation,可以使用commit方法,通過指定Mutation的名稱來調用對應的Mutation函數。例如:this.$store.commit('mutationName', payload)。
  6. 參數(Payload):Mutation函數可以接收一個可選的參數,稱為Payload,用于傳遞額外的資料給Mutation函數。Payload可以是一個對象、數組或簡單的值。
  7. DevTools追蹤:Vuex DevTools可以追蹤和記錄每次Mutation的執行,以便在開發過程中更好地了解和調試State的變化。

通過使用Mutations,可以確定對State的修改是可追蹤和可控的。Mutations的使用應該遵循單一責任原則,每個Mutation應該隻負責修改一個特定的狀态。合理地設計和使用Mutations,可以提高代碼的可維護性和可預測性,并確定在Vuex應用程式中的狀态變更得到正确處理。

Actions(動作)

Actions(動作)是Vuex中用于處理異步操作和封裝業務邏輯的函數。Actions可以包含異步操作、調用API、送出Mutations等,用于處理複雜的業務邏輯或多個Mutations的組合操作。

以下是Actions(動作)的一些關鍵特點和注意事項:

  1. 異步操作:Actions主要用于處理異步操作,如發送網絡請求、定時器操作等。異步操作通常包括一些耗時的操作,不能直接在Mutations中執行。
  2. 送出Mutations:Actions可以通過commit方法來觸發一個或多個Mutations,以實作對State的同步變更。通過送出Mutations,確定對State的修改是可追蹤和可控的。
  3. 調用方式:要觸發Action,可以使用dispatch方法,通過指定Action的名稱來調用對應的Action函數。例如:this.$store.dispatch('actionName', payload)。
  4. 參數(Payload):Action函數可以接收一個可選的參數,稱為Payload,用于傳遞額外的資料給Action函數。Payload可以是一個對象、數組或簡單的值。
  5. 封裝業務邏輯:Actions可以用于封裝複雜的業務邏輯,将多個Mutations的操作組合起來,或者處理一系列相關的異步操作。
  6. 異步操作和回調:由于Actions可以處理異步操作,是以可以使用Promise或async/await等方式來處理異步操作的結果,或在異步操作完成後執行回調函數。
  7. DevTools追蹤:Vuex DevTools可以追蹤和記錄每次Action的執行,以便在開發過程中更好地了解和調試異步操作的流程。

通過使用Actions,可以将複雜的異步操作和業務邏輯從元件中抽離出來,使元件更加專注于視圖的展示和使用者互動。Actions的使用可以提高代碼的可維護性和可測試性,并且與Mutations配合使用,實作了對State的可追蹤和可控的異步修改。

Getters(擷取器)

Getters(擷取器)是Vuex中的一個概念,用于從State中派生出新的資料,類似于計算屬性。Getters允許對State進行包裝、過濾、計算等操作,并傳回派生出的資料供元件使用。

以下是Getters(擷取器)的一些關鍵特點和注意事項:

  1. 派生狀态:Getters用于從State中派生出新的狀态資料,這些資料可以是基于State的計算結果、過濾後的資料、排序後的資料等。
  2. 類似計算屬性:Getters的使用方式類似于計算屬性,通過定義Getter函數來擷取派生狀态的值。Getter函數可以根據State的變化而動态更新。
  3. 緩存:Getters具有緩存機制,隻有當其依賴的State發生變化時,才會重新計算派生狀态的值。這可以提高性能,避免重複計算。
  4. Getter名稱:每個Getter都有一個名稱,用于在元件中通路該Getter。Getter的名稱通常是一個常量字元串,在Vuex Store中定義。
  5. 調用方式:要通路Getter的值,可以通過在元件中使用this.store.getters來通路。例如:`this.store.getters.getterName`。
  6. 參數傳遞:Getter函數可以接收參數,以便根據傳入的參數來進行計算和過濾操作。通過參數傳遞,可以實作更靈活的Getter操作。
  7. 與State和其他Getters的關系:Getter可以依賴于其他Getters和State,這意味着一個Getter可以基于其他Getter的值進行計算。這種依賴關系會自動建立,確定資料的響應性。

通過合理地使用Getters,可以在Vuex中對State進行封裝和轉換,提供更多的資料操作和處理能力。Getters的使用可以簡化元件中對狀态資料的處理邏輯,使其更具可讀性和可維護性。同時,Getters的緩存機制可以提高性能,避免不必要的重複計算。

繼續閱讀