爲Vue.js應用程序開發的狀態管理模式
由 多個組件共享狀態 引發的vue
1. 多個視圖依賴於統一狀態 2. 不一樣視圖的行爲須要變動統一狀態
每一個應用只包含一個Store實例
不能直接修改state。es6
兩種方式:vuex
顯式地提交 (commit) mutation緩存
異同點異步
不一樣點:ide
使用commit的優勢:函數
單一狀態樹
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工具
經過方法訪問:this.$store.getters.getterC(1)性能
相似於事件
同步事務
用來更改Vuex的store中的狀態
每一個mutation包含測試
回調函數 (handler): 進行狀態更改的地方,接收state做爲第一個參數
需遵照Vue的響應規則
Mutation必須是同步函數
devtools 不知道何時回調函數實際上被調用:在回調函數中進行的狀態的改變都是不可追蹤的
異步事務
相似Mutation,不一樣在於:
Action函數接收與store實例具備相同方法和屬性的context對象
actions: { // 常見用法,用es6的參數解構來簡化代碼 actionA({state, commit, getters, dispatch}) { } } // 使用action store.dispatch('actionA').then(() => { })
模塊
解決的問題:應用複雜時(有不少的狀態和邏輯),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: () => { 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數據進行更改
兩種方法
雙向綁定的計算屬性
computed: { message: { get () { return this.$store.state.obj.message }, set (value) { this.$store.commit('updateMessage', value) } } }