Vuex的store中的Module用法及說明
Vuex的store中的Module
1.單一狀態(tài)樹
什么是單一狀態(tài)樹呢?單一狀態(tài)樹可以簡(jiǎn)單得理解成整個(gè)vuex中只有一個(gè)store對(duì)象。
這是官方對(duì)單一狀態(tài)樹的解釋:
Vuex 使用單一狀態(tài)樹——是的,用一個(gè)對(duì)象就包含了全部的應(yīng)用層級(jí)狀態(tài)。至此它便作為一個(gè)“唯一數(shù)據(jù)源 (SSOT (opens new window))”而存在。這也意味著,每個(gè)應(yīng)用將僅僅包含一個(gè) store 實(shí)例。
單一狀態(tài)樹讓我們能夠直接地定位任一特定的狀態(tài)片段,在調(diào)試的過程中也能輕易地取得整個(gè)當(dāng)前應(yīng)用狀態(tài)的快照。
但是當(dāng)我們?nèi)繝顟B(tài)數(shù)據(jù)都往一個(gè)store里面塞的時(shí)候,就會(huì)出現(xiàn)store過于臃腫,幸好Vuex允許將store分割成模塊。單狀態(tài)樹和模塊化并不沖突。
**為了反正store的過于臃腫,Vuex允許將store分割成模塊。**由于使用單一狀態(tài)樹,應(yīng)用的所有狀態(tài)會(huì)集中到一個(gè)比較大的對(duì)象。當(dāng)應(yīng)用變得非常復(fù)雜時(shí),store 對(duì)象就有可能變得相當(dāng)臃腫。這時(shí)我們使用模塊化,能有效解決store 臃腫的狀況。
2.modules
在Vuex中使用modules字段聲明模塊。
store中能定義的屬性在module都能實(shí)現(xiàn),在module中可以像store一樣定義:
state
mutations
actions
getters
modules
(modules的鑲嵌)
//模塊A const moduleA = { state: () => ({ ... }), mutations: { ... }, actions: { ... }, getters: { ... } } //模塊B const moduleB = { state: () => ({ ... }), mutations: { ... }, actions: { ... } //modules: {//模塊中允許進(jìn)行模塊的鑲嵌,但現(xiàn)實(shí)中很少用到} } 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其實(shí)和store并沒有太大的異樣,只不過modules中的getters可以多傳入一個(gè)參數(shù)rootState,用于獲取上一層的state。
const moduleA = { state: { count: 0 }, mutations: { increment (state) { // 這里的 `state` 對(duì)象是模塊的局部狀態(tài)(也就是moduleA的state) state.count++ } }, getters: { doubleCount (state) { // 這里的 `state` 對(duì)象是模塊的局部狀態(tài)(也就是moduleA的state) return state.count * 2 } } } const store = new Vuex.Store({ state: { rootcount: 0 }, mutations: { decrement (state) { // 這里的 `state` 對(duì)象是模塊的局部狀態(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時(shí)無需指定模塊 this.$store.commit('increment') this.$store.commit('decrement') //-------------其他組件中使用模塊中g(shù)etters的時(shí)也是無需指定模塊的 $store.getters.doubleCount
特別的,在模塊中的getters可以傳入三個(gè)參數(shù)state, getters, rootState,分別對(duì)應(yīng):
state
模塊中的stategetters
模塊中的 gettersrootState
上一層模塊或者store的state
const moduleA = { // ... getters: { sumWithRootCount (state, getters, rootState) { return state.count + rootState.count } } }
4.模塊內(nèi)部的 action
同樣,對(duì)于模塊內(nèi)部的 action,局部狀態(tài)通過 context.state
暴露出來,根節(jié)點(diǎn)狀態(tài)則為 context.rootState
還是引用官方的案例:
const moduleA = { // ... actions: { //這里使用{ state, commit, rootState }來接收context中的三個(gè)對(duì)象 incrementIfOddOnRootSum ({ state, commit, rootState }) { if ((state.count + rootState.count) % 2 === 1) { commit('increment') } } } } //-------------其他組件中dispatch到modular中的actions this.$store.dispatch
5.命名空間
默認(rèn)情況下,模塊內(nèi)部的 action、mutation 和 getter 是注冊(cè)在全局命名空間的,也意味這我們可以在全局命名空間中直接使用我們的 action、mutation 和 getter。
回顧一下前面的例子:
//-------------其他組件中commit mutations時(shí)無需指定模塊 this.$store.commit('increment') this.$store.commit('decrement') //-------------其他組件中使用模塊中g(shù)etters的時(shí)也是無需指定模塊的 $store.getters.doubleCount //-------------其他組件中dispatch到modular中的actions this.$store.dispatch
為什么我們能直接訪問到模塊內(nèi)部的 action、mutation 和 getter,那是因?yàn)樵谀J(rèn)情況下,vuex模塊內(nèi)部的 action、mutation 和 getter 是注冊(cè)在全局命名空間的,注冊(cè)在全局命名空間自然能直接通過store來訪問了。
為了模塊更高的封裝性
如果希望你的模塊具有更高的封裝度和復(fù)用性,你可以通過添加 namespaced: true
的方式使其成為帶命名空間的模塊。
當(dāng)模塊被注冊(cè)后,它的所有 getter、action 及 mutation 都會(huì)自動(dòng)根據(jù)模塊注冊(cè)的路徑調(diào)整命名。
這里還是引用官方的例子:
const store = new Vuex.Store({ modules: { account: { namespaced: true, // 模塊內(nèi)容(module assets) state: () => ({ ... }), // 模塊內(nèi)的狀態(tài)已經(jīng)是嵌套的了,使用 `namespaced` 屬性不會(huì)對(duì)其產(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'] } }, // 進(jìn)一步嵌套命名空間 posts: { namespaced: true, state: () => ({ ... }), getters: { popular () { ... } // -> getters['account/posts/popular'] } } } } } })
官方的例子已經(jīng)很明確了,如果還是不理解,我下面列出了上面例子的整個(gè)命名空間下的getters,actions,mutations(括號(hào)中是注冊(cè)的):
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會(huì)注冊(cè)在上一層的命名空間,也就是store/account命名空間中。
? 而模塊account中的posts模塊,使用了namespaced聲明了命名空間,使用有命名空間store/account/posts,也正因如此posts模塊的getters,actions,mutations被注冊(cè)到自己的命名空間下。
使用:
commit('xxx') //沒多級(jí)路徑的,是訪問全局命名空間,也就是store中的 getters['account/isAdmin'] //訪問命名空間account下 dispatch('account/login') commit('account/login') getters['account/profile'] getters['account/posts/popular'] //訪問命名空間account/posts
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- vue3實(shí)現(xiàn)監(jiān)聽store中state狀態(tài)變化的簡(jiǎn)單方法
- vuex之this.$store.dispatch()與this.$store.commit()的區(qū)別及說明
- vuex中this.$store.commit和this.$store.dispatch的基本用法實(shí)例
- vue data中如何獲取使用store中的變量
- vue3中router路由以及vuex的store使用解析
- 在Vue中使用this.$store或者是$route一直報(bào)錯(cuò)的解決
- vue.js的狀態(tài)管理vuex中store的使用詳解
- Vue?關(guān)于Store的用法小結(jié)
相關(guān)文章
vue-router history模式下的微信分享小結(jié)
本篇文章主要介紹了vue-router history模式下的微信分享小結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07Vue.directive 實(shí)現(xiàn)元素scroll邏輯復(fù)用
這篇文章主要介紹了Vue.directive 實(shí)現(xiàn)元素scroll邏輯復(fù)用功能,文中給大家提到元素實(shí)現(xiàn)滾動(dòng)的條件有兩個(gè),具體內(nèi)容詳情大家參考下本文2019-11-11vue awesome swiper異步加載數(shù)據(jù)出現(xiàn)的bug問題
這篇文章主要介紹了vue awesome swiper異步加載數(shù)據(jù)出現(xiàn)的bug問題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07Vue利用路由鉤子token過期后跳轉(zhuǎn)到登錄頁的實(shí)例
下面小編就為大家?guī)硪黄猇ue利用路由鉤子token過期后跳轉(zhuǎn)到登錄頁的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-10-10Vue使用z-tree處理大數(shù)量的數(shù)據(jù)以及生成樹狀結(jié)構(gòu)
這篇文章主要介紹了Vue使用z-tree處理大數(shù)量的數(shù)據(jù)以及生成樹狀結(jié)構(gòu)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04