7.手把手教你使用Vuex - Module

?? 上面我們介紹如何拆分項(xiàng)目怕犁,采用的是按屬性的方式去拆分,將getters/actions/mutations等屬性拆分到不同的文件中慷荔,以及介紹了常量代替XXX事件類型耗跛;接下來,我們介紹一下按另外的一個維度去拆分我們的store节芥,‘按功能’在刺,按功能拆分的話,就是我們的標(biāo)題Module(模塊)头镊。

  • ?? 我們先來看下官方文檔是怎么介紹Module的:


    image.png
    • 看了圖中的描述蚣驼,你或許已經(jīng)區(qū)分了這里使用的按功能拆分Module和我們上次介紹的按屬性拆分的異同了;就像圖中的場景一樣相艇,我們有一個總store颖杏,在這里面根據(jù)不同的功能,我們加了兩個不同的store坛芽,每個store里面維護(hù)自己的state留储,以及自己的actions/mutations/getters翼抠。
  • ?? 不說廢話,我們用代碼實(shí)現(xiàn)一下

    1. 我們在之前的store上获讳,增加一個子模塊机久,名字叫mutou,主要代碼如下:
    • 目錄結(jié)構(gòu)如下
        store
         |___index.js
         |___state.js
         |___mutations.js
         |___getters.js
         |___actions.js
         |___mutation-types.js
         |___getter-types.js
         |___action-types.js
         |___mutou   <---新增mutou文件夾
                |___index.js   <---新增index.js文件赔嚎,新增的模塊我們暫時先不按屬性進(jìn)行拆分了柑船,其實(shí)是完全可以再按屬性進(jìn)行拆分吟税,屬性拆分和功能拆分是完全可以合在一起的
      
    • index.js文件如下:
        import mutou2 from './mutou2/index'
      
        const mutou = {
          state: {
            name:'i am mutou',
          },
          mutations: {
            changeName(state,payload){
              console.log(payload.name);
            }
          },
          getters:{},
        }
        export default mutou
      
    • store/index.js文件修改如下蚌父,引入我們新創(chuàng)建的mutou模塊:
        import Vue from 'vue'
        import Vuex from 'vuex'
        import state from './state'
        import getters from './getters'
        import mutations from './mutations'
        import actions from './actions'
        import mutou from './mutou/index'   <--- 引入mutou模塊
      
        Vue.use(Vuex)
      
        const store = new Vuex.Store({
          modules:{mutou},   <--- 將木頭模塊裝載上
          state,
          getters,
          mutations,
          actions,
        })
        export default store
      
    • 訪問state -- 我們在App.vue測試訪問mutou模塊中的state中的name撮慨,結(jié)果如下:
      console.log(this.$store.state.mutou.name);
      
      image.png
    • 訪問mutation -- 我們在App.vue測試提交mutou模塊中的mutation中的changeName,結(jié)果如下:
      this.$store.commit('changeName',{where:'我是從App.vue進(jìn)來的'})
      
      image.png
  • ?? 1. 模塊的局部狀態(tài)
    我們通過下面的代碼可以了解到在不同的屬性里是怎么訪問模塊內(nèi)的狀態(tài)或者根狀態(tài)

      mutations: {
          changeName(state,payload){
            // state 局部狀態(tài)
            console.log(state)
            console.log(payload.where);
          }
        },
        getters:{
          testGetters (state, getters, rootState) {
            // state 局部狀態(tài)
            console.log(state)
            // 局部 getters,
            console.log(getters)
            // rootState 根節(jié)點(diǎn)狀態(tài)
            console.log(rootState)
          }
        },
        actions: {
          increment ({ state, commit, rootState }) {
            // state 局部狀態(tài)
            console.log(state)
            // rootState 根節(jié)點(diǎn)狀態(tài)
            console.log(rootState)
          }
        }
    
  • ?? 2. 命名空間
    默認(rèn)情況下损晤,模塊內(nèi)部的 action软棺、mutation 和 getter 是注冊在全局命名空間的——這樣使得多個模塊能夠?qū)ν?mutation 或 action 作出響應(yīng)。

      如果希望你的模塊具有更高的**封裝度**和**復(fù)用性**尤勋,你可以通過添加 ```namespaced: true``` 的方式使其成為帶命名空間的模塊喘落。當(dāng)模塊被注冊后,它的所有 getter最冰、action 及 mutation 都會自動根據(jù)模塊注冊的路徑調(diào)整命名瘦棋。例如:
    
    const mutou = {
      namespaced:true,  <--- 增加namespaced屬性,值為true
      state: {
        name:'i am mutou',
      },
    ......
    

    此時暖哨,再次commit我們剛才的changeName的mutation赌朋,瀏覽器會報(bào)找不到mutation的錯誤:

      this.$store.commit('changeName',{where:'我是從App.vue進(jìn)來的'})
    
    image.png

    此時,我們修改為下面的模式篇裁,加上命名空間的路徑即可恢復(fù)正常沛慢。

     this.$store.commit('mutou/changeName',{where:'我是從App.vue進(jìn)來的'})
    

    其余的getters、actions同mutation一樣达布,具體使用可以參考vuex的官方文檔官方文檔的Module在這里团甲。

  • ?? 3. 在帶命名空間的模塊內(nèi)訪問全局內(nèi)容

    • 如果你希望使用全局 state 和 getter,rootState 和 rootGetters 會作為第三和第四參數(shù)傳入 getter黍聂,也會通過 context 對象的屬性傳入 action躺苦。

    • 若需要在全局命名空間內(nèi)分發(fā) action 或提交 mutation,將 { root: true } 作為第三參數(shù)傳給 dispatch 或 commit 即可分冈。

    • 比較簡單圾另,直接貼官方示例代碼:

      modules: {
        foo: {
          namespaced: true,
      
          getters: {
            // 在這個模塊的 getter 中霸株,`getters` 被局部化了
            // 你可以使用 getter 的第四個參數(shù)來調(diào)用 `rootGetters`
            someGetter (state, getters, rootState, rootGetters) {
              getters.someOtherGetter // -> 'foo/someOtherGetter'
              rootGetters.someOtherGetter // -> 'someOtherGetter'
            },
            someOtherGetter: state => { ... }
          },
      
          actions: {
            // 在這個模塊中雕沉, dispatch 和 commit 也被局部化了
            // 他們可以接受 `root` 屬性以訪問根 dispatch 或 commit
            someAction ({ dispatch, commit, getters, rootGetters }) {
              getters.someGetter // -> 'foo/someGetter'
              rootGetters.someGetter // -> 'someGetter'
      
              dispatch('someOtherAction') // -> 'foo/someOtherAction'
              dispatch('someOtherAction', null, { root: true }) // -> 'someOtherAction'
      
              commit('someMutation') // -> 'foo/someMutation'
              commit('someMutation', null, { root: true }) // -> 'someMutation'
            },
            someOtherAction (ctx, payload) { ... }
          }
        }
      }
      
  • ?? 4. 在帶命名空間的模塊注冊全局 action

    • 若需要在帶命名空間的模塊注冊全局 action,你可添加 root: true去件,并將這個 action 的定義放在函數(shù) handler 中坡椒。
    • 我們來實(shí)踐一下扰路,在mutou/index.js的action里面加上:
        globalAction: {
              root: true,
              handler (namespacedContext, payload) {
                console.log('i am in global action...');
              } // -> 'someAction'
        }
      
    • 在App.vue里運(yùn)行,注意倔叼,我沒有加mutou/XXX汗唱,沒有加命名空間的路徑,如果能正常訪問丈攒,即代表該action的確注冊到了全局上哩罪。
        this.$store.dispatch('globalAction')
      
      image.png
  • ?? 5.帶命名空間的綁定函數(shù)

    • 當(dāng)使用 mapState, mapGetters, mapActions 和 mapMutations 這些函數(shù)來綁定帶命名空間的模塊時,寫起來可能比較繁瑣:
        computed: {
          ...mapState({
            a: state => state.some.nested.module.a,
            b: state => state.some.nested.module.b
          })
        },
        methods: {
          ...mapActions([
            'some/nested/module/foo', // -> this['some/nested/module/foo']()
            'some/nested/module/bar' // -> this['some/nested/module/bar']()
          ])
        }
      
    • 對于這種情況巡验,你可以將模塊的空間名稱字符串作為第一個參數(shù)傳遞給上述函數(shù)际插,這樣所有綁定都會自動將該模塊作為上下文。于是上面的例子可以簡化為:
        computed: {
          ...mapState('some/nested/module', {
            a: state => state.a,
            b: state => state.b
          })
        },
        methods: {
          ...mapActions('some/nested/module', [
            'foo', // -> this.foo()
            'bar' // -> this.bar()
          ])
        }
      
    • 而且显设,你可以通過使用 createNamespacedHelpers 創(chuàng)建基于某個命名空間輔助函數(shù)框弛。它返回一個對象,對象里有新的綁定在給定命名空間值上的組件綁定輔助函數(shù):
        import { createNamespacedHelpers } from 'vuex'
      
        const { mapState, mapActions } = createNamespacedHelpers('some/nested/module')
      
        export default {
          computed: {
            // 在 `some/nested/module` 中查找
            ...mapState({
              a: state => state.a,
              b: state => state.b
            })
          },
          methods: {
            // 在 `some/nested/module` 中查找
            ...mapActions([
              'foo',
              'bar'
            ])
          }
        }
      

?? 以上是對module的簡單介紹捕捂,其實(shí)這里就是一種思想瑟枫,分而治之嘛,將復(fù)雜的進(jìn)行拆分指攒,可以更有效的管理慷妙,上面介紹的一些方法就是在拆分后,應(yīng)該注意哪些點(diǎn)允悦,哪些點(diǎn)是因?yàn)椴鸱侄枰驮瓉淼牟徊鸱值倪壿嬜鰠^(qū)分的景殷,哪些是可以避免重復(fù)代碼的操作等等。
其實(shí)以上并不是module的全部澡屡,還有一些比如‘模塊動態(tài)注冊’猿挚、‘模塊重用’等方法這里就沒介紹,如果你在項(xiàng)目中使用到了驶鹉,再進(jìn)行查閱即可绩蜻,有時候不需要完全理解,知道有這個東西就行室埋,知道出了問題的時候該去哪查資料就夠啦办绝。??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市姚淆,隨后出現(xiàn)的幾起案子孕蝉,更是在濱河造成了極大的恐慌,老刑警劉巖腌逢,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件降淮,死亡現(xiàn)場離奇詭異,居然都是意外死亡搏讶,警方通過查閱死者的電腦和手機(jī)佳鳖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進(jìn)店門霍殴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人系吩,你說我怎么就攤上這事来庭。” “怎么了穿挨?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵月弛,是天一觀的道長。 經(jīng)常有香客問我科盛,道長尊搬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任土涝,我火速辦了婚禮佛寿,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘但壮。我一直安慰自己冀泻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布蜡饵。 她就那樣靜靜地躺著弹渔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪溯祸。 梳的紋絲不亂的頭發(fā)上肢专,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天,我揣著相機(jī)與錄音焦辅,去河邊找鬼博杖。 笑死,一個胖子當(dāng)著我的面吹牛筷登,可吹牛的內(nèi)容都是我干的剃根。 我是一名探鬼主播,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼前方,長吁一口氣:“原來是場噩夢啊……” “哼狈醉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起惠险,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤苗傅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后班巩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渣慕,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了摇庙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旱物。...
    茶點(diǎn)故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡遥缕,死狀恐怖卫袒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情单匣,我是刑警寧澤夕凝,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站户秤,受9級特大地震影響码秉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鸡号,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一转砖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鲸伴,春花似錦府蔗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仲吏,卻和暖如春不铆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背裹唆。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工誓斥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人许帐。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓岖食,卻偏偏與公主長得像,于是被迫代替她去往敵國和親舞吭。 傳聞我的和親對象是個殘疾皇子泡垃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評論 2 359

推薦閱讀更多精彩內(nèi)容

  • ### store 1. Vue 組件中獲得 Vuex 狀態(tài) ```js //方式一 全局引入單例類 // 創(chuàng)建一...
    蕓豆_6a86閱讀 732評論 0 3
  • ### store 1. Vue 組件中獲得 Vuex 狀態(tài) ```js //方式一 全局引入單例類 // 創(chuàng)建一...
    蕓豆_6a86閱讀 346評論 0 0
  • 安裝 npm npm install vuex --save 在一個模塊化的打包系統(tǒng)中,您必須顯式地通過Vue.u...
    蕭玄辭閱讀 2,945評論 0 7
  • 由于Vuex的官方文檔在各個模塊之間缺乏一些過渡羡鸥,另外新概念很多蔑穴,使得初讀時總有些云里霧里的感覺。于是本文在官方文...
    一郭鮮閱讀 356評論 0 1
  • State 單一狀態(tài)樹 Vuex使用單一狀態(tài)樹——用一個對象就包含了全部的應(yīng)用層級狀態(tài)惧浴。至此它便作為一個“唯一數(shù)據(jù)...
    oWSQo閱讀 1,093評論 0 0