vuex淺入淺出

什麼是Vuex?

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。vue

Vuex採用和Redux相似的單向數據流的方式來管理數據。用戶界面負責觸發動做(Action)進而改變對應狀態(State),從而反映到視圖(View)上。後端

new Vue({
      el: "#app",
      //state 驅動應用的數據源
      data () {
        return { count: 0 }
      },
      //view 以聲明方式將 state 映射到視圖;
      template: '<div @click="increment">{{ count }}</div>',
      //actions 響應在 view 上的用戶輸入致使的狀態變化。
      methods: {
        increment () {
          this.count++
        }
      }
    })

什麼是「狀態管理模式」?

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

const store = new Vuex.Store({
      //有哪些狀態
      state: {
        count: 0
      },
      actions: {
        incrementAction (store) {
          store.commit('increment')
        }
      },
      //改變,能夠經過調用這個改變的方法來修改state的值
      mutations: {
        increment (state) {//這裏面的方法的第一個就是state,咱們能夠直接修改
          state.count++
        }
      }
    })

這個狀態自管理應用包含如下幾個部分:框架

state,驅動應用的數據源;
view,以聲明方式將 state 映射到視圖;
actions,響應在 view 上的用戶輸入致使的狀態變化異步

可是,當咱們的應用遇到多個組件共享狀態時,
單向數據流的簡潔性很容易被破壞:函數

  • 多個視圖依賴於同一狀態。工具

  • 來自不一樣視圖的行爲須要變動同一狀態。this

對於問題一,傳參的方法對於多層嵌套的組件將會很是繁瑣,而且對於兄弟組件間的狀態傳遞無能爲力。對於問題二,咱們常常會採用父子組件直接引用或者經過事件來變動和同步狀態的多份拷貝。以上的這些模式很是脆弱,一般會致使沒法維護的代碼。
所以,咱們爲何不把組件的共享狀態抽取出來,以一個全局單例模式管理呢?在這種模式下,咱們的組件樹構成了一個巨大的「視圖」,無論在樹的哪一個位置,任何組件都能獲取狀態或者觸發行爲!
另外,經過定義和隔離狀態管理中的各類概念並強制遵照必定的規則,咱們的代碼將會變得更結構化且易維護。
這就是 Vuex 背後的基本思想.spa

什麼狀況下我應該使用 Vuex?

雖然 Vuex 能夠幫助咱們管理共享狀態,但也附帶了更多的概念和框架。這須要對短時間和長期效益進行權衡。
若是您不打算開發大型單頁應用,使用 Vuex 多是繁瑣冗餘的。確實是如此——若是您的應用夠簡單,您最好不要使用 Vuex。一個簡單的 global event bus 就足夠您所需了。可是,若是您須要構建是一箇中大型單頁應用,您極可能會考慮如何更好地在組件外部管理狀態,Vuex 將會成爲天然而然的選擇。設計

Vuex圖解

Backend API: 後端的API
Actions:行爲,響應在 view 上的用戶輸入致使的狀態變化。
Mutations: 突變,mutations, 通俗的理解,裏面裝着一些改變數據方法的集合,這是Veux設計很重要的一點,就是把處理數據邏輯方法所有放在mutations裏面,使得數據和視圖分離。
State: Vuex 使用單一狀態樹——是的,用一個對象就包含了所有的應用層級狀態。至此它便做爲一個「惟一數據源 (SSOT)」而存在。這也意味着,每一個應用將僅僅包含一個 store 實例。
Vue Components: Vue的組件
Devtools: 工具
Mutate: 變異,至關於修改
Render: 提供,響應

clipboard.png

Commit的問題
**爲何不能直接調用mutation方法,而是必須得經過commit來提交mutation呢?
官方解釋道:
更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation。Vuex 中的 mutations 很是相似於事件:每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是咱們實際進行狀態更改的地方,而且它會接受 state 做爲第一個參數:

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state) {
      // 變動狀態
      state.count++
    }
  }
})

你不能直接調用一個 mutation handler。這個選項更像是事件註冊:「當觸發一個類型爲 increment 的 mutation 時,調用此函數。」要喚醒一個 mutation handler,你須要以相應的 type 調用 store.commit 方法:store.commit('increment')

VueComponents—{Dispatch (傳入)}—>Actions—{Commit (提交)}-->Mutations—{Mutate(修改)}—>State—{Render(響應)}-->VueComponents

clipboard.png

State: 至關於組件裏面的data,是用來存放數值。
Getter: 至關於vue裏面的computed
Actions: 至關於vue裏面的methods

const store = new Vuex.Store({
      //有哪些狀態
      state: {
        count: 3
      },
      // 至關於state的計算屬性
      getters: {
        evenOrOdd: state => {
          return state.count % 2 === 0 ? 'even' : 'odd'
        }
      },
      actions: {// 能夠包含異步的代碼
        incrementAction (store, amount) {
          store.commit('increment', amount)
        },
        decrement ({ commit }) {
          commit('decrement')
        }
      },
      //改變,能夠經過調用這個改變的方法來修改state的值
      mutations: {
        increment (state, amount) {//這裏面的方法的第一個就是state,咱們能夠直接修改
          state.count += amount
        },
        decrement (state) {
          state.count--
        }
      }
    })

    var app = new Vue({
      el: "#app",
      computed: {
        counter () {
          return store.state.count
        },
        evenOrOdd () {
          return store.getters.evenOrOdd
        }
      },
      methods: {
        add () {
          store.dispatch('incrementAction', 5)
        },
        decrement () {
          store.dispatch('decrement')
        }
      }
    })
相關文章
相關標籤/搜索