vuex中modules的使用
modules提出的目的:
“由于使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常復雜時,store 對象就有可能變得相當臃腫。”
(來自vuex文檔)
模塊化思想在做項目較大的時候十分有用,下面依據vuex文檔簡單記錄一下modules的使用方式
如何使用modules
const moduleA = {
state: { ... },//局部state
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: { ... },//局部state
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
state:{ ... },//全局state
modules: {
a: moduleA,
b: moduleB
}
})
1.其中moduleA和modulesB的state為局部state,而store對象建立時與modules同級的為全局state
訪問moduleA中的state :store.state.a, 全局state :store.state
2.對于moduleA和moduleB的getters和mutations中,對于參數與全局的getters和mutations存在一定區別
getters和mutations中第一個參數的state為局部state,
getters的第二個參數為全局getters,第三個為根state(rootState)
3.對于moduleA和moduleB的和mutations中
局部state通過context.state,全局state通過content.rootState ,全局getters通過rootGetters
actions: {
test({ state, rootState }) {
....
}
4.moduleA和moduleB除了state為局部,其他stategetters和mutations,actions可以全局直接使用,但參數的作用域全局的存在不同
module 的命名空間
什么是命名空間,就是在module中添加一個屬性,namespaced: true, 就完成了,而命的名字就是在全局中導入的module的名字,
如上邊代碼中moduleA對應的a為其名字。
注意:module中state不受命名空間影響,本身就是局部state的
而getters和mutations,actions在命名后為局部,不能直接在全局調用
代碼來自vuex文檔
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,mutations和actions的話,需要注意一些
getters存在四個參數,state(局部), getters(局部), rootState(全局), rootGetters(全局)
例子
getters: {
// 在這個模塊的 getter 中,`getters` 被局部化了
// 你可以使用 getter 的第四個參數來調用 `rootGetters`
someGetter (state, getters, rootState, rootGetters) {
getters.someOtherGetter // -> 'foo/someOtherGetter'
rootGetters.someOtherGetter // -> 'someOtherGetter'
},
someOtherGetter: state => { ... }
},
對于mutation,不存在rootState可以訪問全局state
對于action,存在rootState和rootGetters
接下來一個問題,因為命名空間,commit和dispatch都局部化,所以如何使用全局的commit和dispatch呢
答案是:通過傳入{root:true}作為第三個參數打開路徑調用全局的commit和dispatch
直接上例子
actions: {
// 在這個模塊中, dispatch 和 commit 也被局部化了
// 他們可以接受 `root` 屬性以訪問根 dispatch 或 commit
someAction ({ dispatch, commit, getters, rootGetters }) {
dispatch('someOtherAction') // -> 'foo/someOtherAction'
dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
commit('someMutation') // -> 'foo/someMutation'
commit('someMutation', null, { root: true }) // -> 'someMutation'
},
如果你想在module中注冊一個全局的actions,可以通過如下方式,
在actions中添加一個屬性(action函數名字),通過對象方式,添加root為true的屬性以及在handle中添加action方法{root:true,handle(){...}}
actions: {
someAction: {
root: true,
handler (namespacedContext, payload) { ... } // -> 'someAction'
}
}
接下來是如何將命名空間與語法糖(mapState,mapMutations,mapGetters,mapActions)結合起來
...mapState({
a: state => state.moduleA.a,
b: state => state.moduleB.b
})
...mapGeters({
a:"moduleA/a"
})
...mapActions([‘moduleA/foo’]) =>使用為 this[moduleA/foo]()
...mapMutations([‘moduleA/foo’])=>使用為 this[moduleA/foo]()
如上所見,簡單直白
關于上邊為什么mapState和mapGetters為什么要采用這種方式,起一個別名a,由于不起別名a,如何采用同Action和Mutation一樣的寫法的話
emm,那么使用為this['moduleA/a'],但是在template使用模板語法的時候表示為{{this['moduleA/a']}}得不出想要的數據,所以采用別名
獲取另一種寫法
...mapState(“moduleA”,["a"])
...mapGetters("moduleA",["a"] ...mapActions("moduleA",[‘foo’]) =>使用為 this.foo() ...mapMutations("moduleA",[‘foo’]) =>使用為 this.foo()
如果你覺得需要些指定命名的路徑比較麻煩,你可以調用createNamespacedHelpers這個創建某個命名空間的輔助函數
import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('moduleA')
...mapState({
a: state => state.a,
b: state => state.b
})
...mapActions([‘foo’]) =>使用為 this.foo()
...mapMutations([‘foo’]) =>使用為 this.foo()
總結
以上是生活随笔為你收集整理的vuex中modules的使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手擀面的做法(手擀面的制作)
- 下一篇: csgo交易能提现吗(csgo皮肤交易平