Vuex的store中的Module
Vuex的store中的Module
1.單一狀態樹:
什么是單一狀態樹呢?單一狀態樹可以簡單得理解成整個vuex中只有一個store對象。
這是官方對單一狀態樹的解釋:
Vuex 使用單一狀態樹——是的,用一個對象就包含了全部的應用層級狀態。至此它便作為一個“唯一數據源 (SSOT (opens new window))”而存在。這也意味著,每個應用將僅僅包含一個 store 實例。單一狀態樹讓我們能夠直接地定位任一特定的狀態片段,在調試的過程中也能輕易地取得整個當前應用狀態的快照。
但是當我們全部狀態數據都往一個store里面塞的時候,就會出現store過于臃腫,幸好Vuex允許將store分割成模塊。單狀態樹和模塊化并不沖突。
**為了反正store的過于臃腫,Vuex允許將store分割成模塊。**由于使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常復雜時,store 對象就有可能變得相當臃腫。這時我們使用模塊化,能有效解決store 臃腫的狀況。
2.modules
在Vuex中使用modules字段聲明模塊。store中能定義的屬性在module都能實現,在module中可以像store一樣定義:state,mutations,actions,getters,modules(modules的鑲嵌)
//模塊A const moduleA = {state: () => ({ ... }),mutations: { ... },actions: { ... },getters: { ... } }//模塊B const moduleB = {state: () => ({ ... }),mutations: { ... },actions: { ... }//modules: {//模塊中允許進行模塊的鑲嵌,但現實中很少用到} }const store = new Vuex.Store({//通過modules指定模塊modules: {a: moduleA,b: moduleB} })store.state.a // -> moduleA 的狀態 store.state.b // -> moduleB 的狀態3.模塊內部的 mutation 和 getters
在modules中的mutation 和 getters其實和store并沒有太大的異樣,只不過modules中的getters可以多傳入一個參數rootState,用于獲取上一層的state。
const moduleA = {state: {count: 0},mutations: {increment (state) {// 這里的 `state` 對象是模塊的局部狀態(也就是moduleA的state)state.count++}},getters: {doubleCount (state) {// 這里的 `state` 對象是模塊的局部狀態(也就是moduleA的state)return state.count * 2}} }const store = new Vuex.Store({state: {rootcount: 0},mutations: {decrement (state) {// 這里的 `state` 對象是模塊的局部狀態(也就是moduleA的state)state.count--}},modules: {a: moduleA} })//-------------在其他組件中使用模塊中的state需要指明模塊 store.state // -> moduleA 的狀態 store.state.rootcount // -> store中的rootcount store.state.a // -> moduleA 的狀態 store.state.a.count //moduleA中的count//-------------其他組件中commit mutations時無需指定模塊 this.$store.commit('increment') this.$store.commit('decrement') //-------------其他組件中使用模塊中getters的時也是無需指定模塊的 $store.getters.doubleCount特別的,在模塊中的getters可以傳入三個參數state, getters, rootState,分別對應:
- state 模塊中的state
- getters 模塊中的 getters
- rootState 上一層模塊或者store的state
4.模塊內部的 action
同樣,對于模塊內部的 action,局部狀態通過 context.state 暴露出來,根節點狀態則為 context.rootState
還是引用官方的案例:
const moduleA = {// ...actions: {//這里使用{ state, commit, rootState }來接收context中的三個對象incrementIfOddOnRootSum ({ state, commit, rootState }) {if ((state.count + rootState.count) % 2 === 1) {commit('increment')}}} }//-------------其他組件中dispatch到modular中的actions this.$store.dispatch5.命名空間
默認情況下,模塊內部的 action、mutation 和 getter 是注冊在全局命名空間的,也意味這我們可以在全局命名空間中直接使用我們的 action、mutation 和 getter。回顧一下前面的例子:
//-------------其他組件中commit mutations時無需指定模塊 this.$store.commit('increment') this.$store.commit('decrement')//-------------其他組件中使用模塊中getters的時也是無需指定模塊的 $store.getters.doubleCount//-------------其他組件中dispatch到modular中的actions this.$store.dispatch為什么我們能直接訪問到模塊內部的 action、mutation 和 getter,那是因為在默認情況下,vuex模塊內部的 action、mutation 和 getter 是注冊在全局命名空間的,注冊在全局命名空間自然能直接通過store來訪問了。
為了模塊更高的封裝性
如果希望你的模塊具有更高的封裝度和復用性,你可以通過添加 namespaced: true 的方式使其成為帶命名空間的模塊。當模塊被注冊后,它的所有 getter、action 及 mutation 都會自動根據模塊注冊的路徑調整命名。這里還是引用官方的例子:
const store = new Vuex.Store({modules: {account: {namespaced: true,// 模塊內容(module assets)state: () => ({ ... }), // 模塊內的狀態已經是嵌套的了,使用 `namespaced` 屬性不會對其產生影響getters: {isAdmin () { ... } // -> getters['account/isAdmin']},actions: {login () { ... } // -> dispatch('account/login')},mutations: {login () { ... } // -> commit('account/login')},// 嵌套模塊modules: {// 繼承父模塊的命名空間myPage: {state: () => ({ ... }),getters: {profile () { ... } // -> getters['account/profile']}},// 進一步嵌套命名空間posts: {namespaced: true,state: () => ({ ... }),getters: {popular () { ... } // -> getters['account/posts/popular']}}}}} })官方的例子已經很明確了,如果還是不理解,我下面列出了上面例子的整個命名空間下的getters,actions,mutations(括號中是注冊的):
-
store (空)
-
store/account
- getters (isAdmin,profile)
- actions (login)
- mutations (login)
-
store/account/posts
- getters (popular)
- actions (空)
- mutations (空)
解析:
? 全局命名空間(store)中只定義了modules,所以為空,而模塊account使用了namespaced聲明了命名空間,所以有命名空間store/account 。
? 而模塊account中的myPage模塊沒有使用namespaced聲明了命名空間,所以myPage模塊的getters的profile會注冊在上一層的命名空間,也就是store/account命名空間中。
? 而模塊account中的posts模塊,使用了namespaced聲明了命名空間,使用有命名空間store/account/posts,也正因如此posts模塊的getters,actions,mutations被注冊到自己的命名空間下。
使用:
commit('xxx') //沒多級路徑的,是訪問全局命名空間,也就是store中的 getters['account/isAdmin'] //訪問命名空間account下 dispatch('account/login') commit('account/login') getters['account/profile'] getters['account/posts/popular'] //訪問命名空間account/posts?
?
?
總結
以上是生活随笔為你收集整理的Vuex的store中的Module的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 九阴真经暮色之村攻略
- 下一篇: 抖音最像夫妻脸视频怎么拍