由於使用單一狀態樹,應用的所有狀態會集中到乙個比較大的物件。當應用變得非常複雜時,store 物件就有可能變得相當臃腫。
為了解決以上問題,vuex 允許我們將 store 分割成模組(module)。每個模組擁有自己的 state、mutation、action、getter、甚至是巢狀子模組——從上至下進行同樣方式的分割:
const modulea = ,
mutations: ,
actions: ,
getters:
}const moduleb = ,
mutations: ,
actions:
}const store = new vuex.store(
})store.state.a // -> modulea 的狀態
store.state.b // -> moduleb 的狀態
對於模組內部的 mutation 和 getter,接收的第乙個引數是模組的區域性狀態物件。
const modulea = ,
mutations:
},getters:
}}
同樣,對於模組內部的 action,區域性狀態通過context.state
暴露出來,根節點狀態則為context.rootstate
:
const modulea = )
}}}
對於模組內部的 getter,根節點狀態會作為第三個引數暴露出來:
const modulea =
}}
預設情況下,模組內部的 action、mutation 和 getter 是註冊在全域性命名空間的——這樣使得多個模組能夠對同一 mutation 或 action 作出響應。
如果希望你的模組具有更高的封裝度和復用性,你可以通過新增namespaced: true
的方式使其成為帶命名空間的模組。當模組被註冊後,它的所有 getter、action 及 mutation 都會自動根據模組註冊的路徑調整命名。例如:
const store = new vuex.store(, // 模組內的狀態已經是巢狀的了,使用 `namespaced` 屬性不會對其產生影響
getters: // -> getters['account/isadmin']
},actions: // -> dispatch('account/login')
},mutations: // -> commit('account/login')
},// 巢狀模組
modules: ,
getters: // -> getters['account/profile']}},
// 進一步巢狀命名空間
posts: ,
getters: // -> getters['account/posts/popular']}}
}}
}})
啟用了命名空間的 getter 和 action 會收到區域性化的getter
,dispatch
和commit
。換言之,你在使用模組內容(module assets)時不需要在同一模組內額外新增空間名字首。更改namespaced
屬性後不需要修改模組內的**。
#在帶命名空間的模組內訪問全域性內容(global assets)
如果你希望使用全域性 state 和 getter,rootstate
和rootgetters
會作為第三和第四引數傳入 getter,也會通過context
物件的屬性傳入 action。
若需要在全域性命名空間內分發 action 或提交 mutation,將作為第三引數傳給
dispatch
或commit
即可。
modules: ,
someothergetter: state =>
},actions: ) ) // -> 'someotheraction'
commit('somemutation') // -> 'foo/somemutation'
commit('somemutation', null, ) // -> 'somemutation'
},someotheraction (ctx, payload)
}}}
#在帶命名空間的模組註冊全域性 action
若需要在帶命名空間的模組註冊全域性 action,你可新增root: true
,並將這個 action 的定義放在函式handler
中。例如:
)
},modules: // -> 'someaction'}}
}}}
#帶命名空間的繫結函式
當使用mapstate
,mapgetters
,mapactions
和mapmutations
這些函式來繫結帶命名空間的模組時,寫起來可能比較繁瑣:
computed: )
},methods:
對於這種情況,你可以將模組的空間名稱字串作為第乙個引數傳遞給上述函式,這樣所有繫結都會自動將該模組作為上下文。於是上面的例子可以簡化為:
computed: )
},methods:
而且,你可以通過使用createnamespacedhelpers
建立基於某個命名空間輔助函式。它返回乙個物件,物件裡有新的繫結在給定命名空間值上的元件繫結輔助函式:
import from 'vuex'
const = createnamespacedhelpers('some/nested/module')
export default )
},methods:
}
#給外掛程式開發者的注意事項
如果你開發的外掛程式(plugin)提供了模組並允許使用者將其新增到 vuex store,可能需要考慮模組的空間名稱問題。對於這種情況,你可以通過外掛程式的引數物件來允許使用者指定空間名稱:
// 通過外掛程式的引數物件得到空間名稱
// 然後返回 vuex 外掛程式函式
export function createplugin (options = {})
}
在 store 建立之後,你可以使用store.registermodule
方法註冊模組:
// 註冊模組 `mymodule`
store.registermodule('mymodule', )
// 註冊巢狀模組 `nested/mymodule`
store.registermodule(['nested', 'mymodule'], )
之後就可以通過store.state.mymodule
和store.state.nested.mymodule
訪問模組的狀態。
模組動態註冊功能使得其他 vue 外掛程式可以通過在 store 中附加新模組的方式來使用 vuex 管理狀態。例如,vuex-router-sync
外掛程式就是通過動態註冊模組將 vue-router 和 vuex 結合在一起,實現應用的路由狀態管理。
你也可以使用store.unregistermodule(modulename)
來動態解除安裝模組。注意,你不能使用此方法解除安裝靜態模組(即建立 store 時宣告的模組)。
#保留 state
在註冊乙個新 module 時,你很有可能想保留過去的 state,例如從乙個服務端渲染的應用保留 state。你可以通過preservestate
選項將其歸檔:store.registermodule('a', module, )
。
當你設定preservestate: true
時,該模組會被註冊,action、mutation 和 getter 會被新增到 store 中,但是 state 不會。這裡假設 store 的 state 已經包含了這個 module 的 state 並且你不希望將其覆寫。
有時我們可能需要建立乙個模組的多個例項,例如:
如果我們使用乙個純物件來宣告模組的狀態,那麼這個狀態物件會通過引用被共享,導致狀態物件被修改時 store 或模組間資料互相汙染的問題。
實際上這和 vue 元件內的data
是同樣的問題。因此解決辦法也是相同的——使用乙個函式來宣告模組狀態(僅 2.3.0+ 支援):
const myreusablemodule =
},// mutation, action 和 getter 等等...
}
Vue學習筆記 Vuex之Getters
getters只有當資料發生改變時才會重新倍計算 類似於計算屬性 需求 1 獲取uers年齡 age 大於18歲的資料 state getters getnum state,getters 需求 2 獲取uers年齡 age 大於18歲資料的數量 getters getnum state,gette...
vue學習筆記 vuex
store 倉庫部分 資料儲存 state state 可以顯示的展示資料格式等等,形象理解就是為資料佔位置。思考 在什麼位置可以 顯示的生成資料,除state內以外?獲取資料 getters getters 寫入獲取資料的方法,vuex提供了 filter,find等篩選資料的方法 狀態變更 mu...
Vue學習筆記 十一 Vuex
目錄vuex 是乙個為 vue 應用程式開發的狀態管理模式,它用集中式儲存來管理應用所有元件的狀態 簡單來說,它的作用就是把所有元件的共享狀態抽取出來,以乙個全域性單例的模式進行管理 我們可以把 vuex 理解成乙個 store,裡面儲存著所有元件共享的 state 資料 和 mutations 操...