Vuex學習筆記

Vuex

爲Vue.js應用程序開發的狀態管理模式

解決的問題

由 多個組件共享狀態 引發的vue

1. 多個視圖依賴於統一狀態
2.  不一樣視圖的行爲須要變動統一狀態

enter image description here

Store

每一個應用只包含一個Store實例
  1. Vuex 的狀態存儲是響應式的。store 中的state狀態更新當即觸發組件更新
  2. 不能直接修改state。es6

    • 兩種方式:vuex

      • 能夠經過 this.$store.state.變量 = xxx; 進行修改
      • 顯式地提交 (commit) mutation緩存

        • this.$store.dispatch(actionType, payload) => mapActions 使用action進行更改,異步
        • this.$store.commit(commitType, payload) => mapMutations 使用mutation進行更改,同步
      • 能夠經過 this.$store.state.變量 = xxx; 進行修改
    • strict模式使用第一種方法vue會throw error : [vuex] Do not mutate vuex store state outside mutation handlers。
    • 異同點異步

      • 共同點:都能觸發視圖更新(響應式修改)
      • 不一樣點:ide

        • strict模式下,使用第一種方法vue會throw error : [vuex] Do not mutate vuex store state outside mutation handlers。
    • 使用commit的優勢:函數

      • vuex可以記錄每一次state的變化記錄,保存狀態快照,實現時間漫遊/回滾之類的操做。

核心概念

State 單一狀態樹

  • 全局的應用層級狀態 -- 惟一數據源
  • 經過this.$store.state能夠訪問
  • mapState 輔助函數:幫助在組件中引入state相關屬性,做爲組件的計算屬性

Getter state派生狀態

能夠認爲是 store的計算屬性 : getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被從新計算
getters: {
    // 能夠經過第二個參數getters來使用其餘getter
    getterA: (state, getters) => {
        return getters.getterB.length
    },
    getterB: (state) => {
        return state.todoList;
    },
    getterC: (state) => (id) => {
        return state.todoList[id];
    }
}
  • 經過屬性訪問:this.$store.getters.getterA工具

    • getter做爲Vue的響應式系統的一部分緩存其中
  • 經過方法訪問:this.$store.getters.getterC(1)性能

    • 每次都會去進行調用,而不會緩存結果
  • mapGetters: 將getters數據映射到局部(組件)計算屬性

Mutation 相似於事件 同步事務

用來更改Vuex的store中的狀態

每一個mutation包含測試

  • 事件類型(type)
  • 回調函數 (handler): 進行狀態更改的地方,接收state做爲第一個參數

    • 經過store.commit方法 調用mutation handler
    • (state, payload)=> {}
    • payload: 向store.commit傳入的額外的參數

需遵照Vue的響應規則

  1. store中初始化全部所需屬性
  2. 添加新屬性用 Vue.set(obj, 'newProp', 123); 或者 state.obj = { ...state.obj, newProp: 123}

Mutation必須是同步函數

devtools 不知道何時回調函數實際上被調用:在回調函數中進行的狀態的改變都是不可追蹤的

Action 異步事務

相似Mutation,不一樣在於:

  • Action 提交的是mutation,而不是直接變動狀態
  • 可包含任意異步操做

Action函數接收與store實例具備相同方法和屬性的context對象

actions: {
    // 常見用法,用es6的參數解構來簡化代碼
    actionA({state, commit, getters, dispatch}) {
    }
}

// 使用action
store.dispatch('actionA').then(() => {
})

Module 模塊

解決的問題:應用複雜時(有不少的狀態和邏輯),store對象會很臃腫

每一個模塊擁有本身的state、getter、mutation、action、嵌套子模塊module

命名空間

  • 默認註冊在全局命名空間,經過設置namespaced:true 可使其成爲帶命名空間的模塊(局部化
  • 帶命名空間的模塊內訪問全局內容:

    • state & getters

      getters: {
          // 局部化後
          getterA: (state, getters, rootState, rootGetters) => {
          }
      }
      actions: {
          actionA: ({dispatch, commit, getters, rootGetters, state, rootState}) => {
          }
      }
    • action & mutation: 第三參數設爲{root: true}
    action: () => {
            dispatch('actionA', null, { root:true });
            committ('mutationA', null, { root:true });
        }
  • 在帶命名空間的模塊內註冊全局action

    actions: {
            actionA: {
                root: true,
                handler(namespacedContext, payload) { ... }
            }
        }

模塊動態註冊: store.registerModule('moduleName', {})

- Vue插件能夠在store中附加新模塊,從而使用vuex來管理狀態。例如:vuex-router-sync

模塊卸載:store.unregisterModule(moduleName)

保留state: store.registerModule('a', module, { preserveState: true })

模塊重用:

const MyReusableModule = {
  state () {
    return {
      foo: 'bar'
    }
  },
  // mutation, action 和 getter 等等...
}

插件

在插件中不容許直接修改狀態——相似於組件,只能經過提交 mutation 來觸發變化。
const myPlugin = store => {
 // 當 store 初始化後調用
  store.subscribe((mutation, state) => {
    // 每次 mutation 以後調用
    // mutation 的格式爲 { type, payload }
  })
}
const store = new Vuex.Store({
 // ...
  plugins: [myPlugin]
})

嚴格模式

開啓嚴格模式,僅需在建立 store 的時候傳入 strict: true

const store = new Vuex.Store({
  // ...
  strict: true
})

在嚴格模式下,不管什麼時候發生了狀態變動且不是由 mutation 函數引發的,將會拋出錯誤。這能保證全部的狀態變動都能被調試工具跟蹤到

不要在發佈環境下啓用嚴格模式: 嚴格模式會深度監測狀態樹來檢測不合規的狀態變動,會有性能損失

表單處理

嚴格模式下,不要用v-model綁定state數據
** 這樣會不使用mutation對state數據進行更改

兩種方法

  • v-model綁定value,監聽value變化而後在事件回調中使用mutation去修改state數據
  • 雙向綁定的計算屬性

    computed: {
      message: {
        get () {
          return this.$store.state.obj.message
        },
        set (value) {
          this.$store.commit('updateMessage', value)
        }
      }
    }

測試

熱重載

相關文章
相關標籤/搜索