狀態管理


目錄



類別Flux 狀態管理的官方實作


# #由於狀態零散地分佈在許多組件和組件之間的交互中,大型應用複雜度也經常逐漸增長。為了解決這個問題,Vue 提供

vuex

:我們有受到 Elm 啟發的狀態管理函式庫。 vuex 甚至整合到 vue-devtools,無需配置即可進行時光旅行調試 (time travel debugging)

React 的開發者請參考以下資訊

如果你是來自React 的開發者,你可能會對Vuex 和Redux 間的差異表示關注,Redux 是React 生態環境中最受歡迎的Flux 實作。 Redux 事實上無法感知視圖層,所以它能夠輕鬆的通過一些簡單綁定

和 Vue 一起使用。 Vuex 差別在於它是一個專門為 Vue 應用所設計。這使得它能夠更好地和 Vue 進行整合,同時提供簡潔的 API 和改善的開發體驗。


簡單狀態管理開始使用#經常被忽略的是,Vue 應用程式中原始資料物件的實際來源- 當存取資料物件時,一個Vue 實例只是簡單的代理存取。所以,如果你有一處需要被多個實例間共享的狀態,可以簡單地透過維護一份資料來實現共享:

const sourceOfTruth = {}

const vmA = new Vue({
  data: sourceOfTruth
})

const vmB = new Vue({
  data: sourceOfTruth
})

現在當sourceOfTruth 發生變化,

vmA### 和###vmB### 都會自動的更新引用它們的視圖。子元件們的每個實例也會透過 ###this.$root.$data### 去存取。現在我們有了唯一的資料來源,但是,調試將會變成惡夢。任何時間,我們應用程式中的任何部分,在任何資料改變後,都不會留下變更過的記錄。 ######為了解決這個問題,我們採用一個簡單的 ###store 模式###:###
var store = {
  debug: true,
  state: {
    message: 'Hello!'
  },
  setMessageAction (newValue) {
    if (this.debug) console.log('setMessageAction triggered with', newValue)
    this.state.message = newValue
  },
  clearMessageAction () {
    if (this.debug) console.log('clearMessageAction triggered')
    this.state.message = ''
  }
}

要注意,所有 store 中 state 的改變,都放置在 store 本身的 action 中去管理。這種集中式狀態管理能夠被更容易理解哪種類型的 mutation 將會發生,以及它們是如何被觸發。當錯誤出現時,我們現在也會有一個 log 記錄 bug 之前發生了什麼事。

此外,每個實例/元件仍然可以擁有和管理自己的私有狀態:

var vmA = new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  }
})

var vmB = new Vue({
  data: {
    privateState: {},
    sharedState: store.state
  }
})

1568869980606995.png

重要的是,注意你不應該在 action 中 替換原始的狀態對象 - 元件和 store 需要引用同一個共享對象,mutation 才能夠被觀察

接著我們繼續延伸約定,元件不允許直接修改屬於store 實例的state,而應執行action 來分發(dispatch) 事件通知store 去改變,我們最終達成了 Flux 架構。這樣約定的好處是,我們能夠記錄所有 store 中發生的 state 改變,同時實現能做到記錄變更 (mutation)、保存狀態快照、歷史回滾/時光旅行的先進的調試工具。

說了一圈其實又回到了vuex,如果你已經讀到這兒,或許可以去嘗試!