Vuex的store中的Module用法及說明
Vuex的store中的Module
1.單一狀態(tài)樹
什么是單一狀態(tài)樹呢?單一狀態(tài)樹可以簡單得理解成整個vuex中只有一個store對象。
這是官方對單一狀態(tài)樹的解釋:
Vuex 使用單一狀態(tài)樹——是的,用一個對象就包含了全部的應用層級狀態(tài)。至此它便作為一個“唯一數(shù)據(jù)源 (SSOT (opens new window))”而存在。這也意味著,每個應用將僅僅包含一個 store 實例。
單一狀態(tài)樹讓我們能夠直接地定位任一特定的狀態(tài)片段,在調(diào)試的過程中也能輕易地取得整個當前應用狀態(tài)的快照。
但是當我們?nèi)繝顟B(tài)數(shù)據(jù)都往一個store里面塞的時候,就會出現(xiàn)store過于臃腫,幸好Vuex允許將store分割成模塊。單狀態(tài)樹和模塊化并不沖突。
**為了反正store的過于臃腫,Vuex允許將store分割成模塊。**由于使用單一狀態(tài)樹,應用的所有狀態(tài)會集中到一個比較大的對象。當應用變得非常復雜時,store 對象就有可能變得相當臃腫。這時我們使用模塊化,能有效解決store 臃腫的狀況。
2.modules
在Vuex中使用modules字段聲明模塊。
store中能定義的屬性在module都能實現(xiàn),在module中可以像store一樣定義:
statemutationsactionsgettersmodules(modules的鑲嵌)
//模塊A
const moduleA = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
//模塊B
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
//modules: {//模塊中允許進行模塊的鑲嵌,但現(xiàn)實中很少用到}
}
const store = new Vuex.Store({
//通過modules指定模塊
modules: {
a: moduleA,
b: moduleB
}
})
store.state.a // -> moduleA 的狀態(tài)
store.state.b // -> moduleB 的狀態(tài)
3.模塊內(nèi)部的 mutation 和 getters
在modules中的mutation 和 getters其實和store并沒有太大的異樣,只不過modules中的getters可以多傳入一個參數(shù)rootState,用于獲取上一層的state。
const moduleA = {
state: {
count: 0
},
mutations: {
increment (state) {
// 這里的 `state` 對象是模塊的局部狀態(tài)(也就是moduleA的state)
state.count++
}
},
getters: {
doubleCount (state) {
// 這里的 `state` 對象是模塊的局部狀態(tài)(也就是moduleA的state)
return state.count * 2
}
}
}
const store = new Vuex.Store({
state: {
rootcount: 0
},
mutations: {
decrement (state) {
// 這里的 `state` 對象是模塊的局部狀態(tài)(也就是moduleA的state)
state.count--
}
},
modules: {
a: moduleA
}
})
//-------------在其他組件中使用模塊中的state需要指明模塊
store.state // -> moduleA 的狀態(tài)
store.state.rootcount // -> store中的rootcount
store.state.a // -> moduleA 的狀態(tài)
store.state.a.count //moduleA中的count
//-------------其他組件中commit mutations時無需指定模塊
this.$store.commit('increment')
this.$store.commit('decrement')
//-------------其他組件中使用模塊中getters的時也是無需指定模塊的
$store.getters.doubleCount
特別的,在模塊中的getters可以傳入三個參數(shù)state, getters, rootState,分別對應:
state模塊中的stategetters模塊中的 gettersrootState上一層模塊或者store的state
const moduleA = {
// ...
getters: {
sumWithRootCount (state, getters, rootState) {
return state.count + rootState.count
}
}
}
4.模塊內(nèi)部的 action
同樣,對于模塊內(nèi)部的 action,局部狀態(tài)通過 context.state 暴露出來,根節(jié)點狀態(tài)則為 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.dispatch
5.命名空間
默認情況下,模塊內(nèi)部的 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
為什么我們能直接訪問到模塊內(nèi)部的 action、mutation 和 getter,那是因為在默認情況下,vuex模塊內(nèi)部的 action、mutation 和 getter 是注冊在全局命名空間的,注冊在全局命名空間自然能直接通過store來訪問了。
為了模塊更高的封裝性
如果希望你的模塊具有更高的封裝度和復用性,你可以通過添加 namespaced: true 的方式使其成為帶命名空間的模塊。
當模塊被注冊后,它的所有 getter、action 及 mutation 都會自動根據(jù)模塊注冊的路徑調(diào)整命名。
這里還是引用官方的例子:
const store = new Vuex.Store({
modules: {
account: {
namespaced: true,
// 模塊內(nèi)容(module assets)
state: () => ({ ... }), // 模塊內(nèi)的狀態(tài)已經(jīng)是嵌套的了,使用 `namespaced` 屬性不會對其產(chǎn)生影響
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']
}
}
}
}
}
})
官方的例子已經(jīng)很明確了,如果還是不理解,我下面列出了上面例子的整個命名空間下的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
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
基于Vue中使用節(jié)流Lodash throttle詳解
今天小編就為大家分享一篇基于Vue中使用節(jié)流Lodash throttle詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10
解決vue v-for 遍歷循環(huán)時key值報錯的問題
今天小編就為大家分享一篇解決vue v-for 遍歷循環(huán)時key值報錯的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09
如何解決vuex在頁面刷新后數(shù)據(jù)被清除的問題
這篇文章主要介紹了如何解決vuex在頁面刷新后數(shù)據(jù)被清除的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05
Javascript vue.js表格分頁,ajax異步加載數(shù)據(jù)
這篇文章主要介紹了Javascript vue.js表格分頁,ajax異步加載數(shù)據(jù)的相關資料,需要的朋友可以參考下2016-10-10
element table跨分頁多選及回顯的實現(xiàn)示例
本文主要介紹了element table跨分頁多選及回顯的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
vue-cli項目中img如何使用require動態(tài)獲取圖片
這篇文章主要介紹了vue-cli項目中img如何使用require動態(tài)獲取圖片,具有很好的參考價值,希望對大家有所幫助。2022-09-09

