vuex中modules的使用場景和注意事項

store 拆分紅 modules 過程

以前的項目一直是store下面放各類js文件(index.js、state.js、getter.js、mutation-types.js、mutations.js、action.js); 以下圖javascript

└── store
    ├── index.js          # 咱們組裝模塊並導出 store 的地方
    ├── actions.js        # 根級別的 action
    ├── mutations.js      # 根級別的 mutation
    ├── state.js          # 根級別的 state
    └── getter.js
複製代碼

使用單一的狀態樹,應用的全部狀態都會集中在一個比較大的對象上面,隨着項目需求的不斷增長,狀態樹也會變得愈來愈臃腫,增長了狀態樹維護的複雜度,並且代碼變得沉長;所以咱們須要modules來爲咱們的狀態樹分隔成不一樣的模塊,每一個模塊擁有本身的state,getters,mutations,actions;並且容許每一個module裏面嵌套子module;以下:html

└── store
    ├── index.js          # 咱們組裝模塊並導出 store 的地方
    ├── actions.js        # 根級別的 action
    ├── mutations.js      # 根級別的 mutation
    ├── state.js          # 根級別的 state
    └── modules
        ├── module1.js   # 模塊1的state樹
        └── module2.js   # 模塊2的state樹
複製代碼

模塊module1.js內部的代碼結構以下vue

import { WIDTH_ADD } from '@/store/mutation-types.js'  // 引入事件類型

export default {
    namespaced: true,
    state: {
        width: 100,
        height: 50
    },
    getters: {
        modulegGetWidth(state, getters, rootState) {
            return state.width
        },
        modulegetHeight(state, getters, rootState) {
            return state.height
        }
    },
    mutations: {
        [WIDTH_ADD](state) {   // 使用常量替代 Mutation 事件類型
            return state.width++
        },
        addHeight(state) {    // 不使用常量
            return state.height++
        }
    },
    actions: {
        
    }
}
複製代碼

註冊到根state。
index.js以下java

import state from './state'
import getters from './getters'
import mutations from './mutations'
import actions from './actions'
import module1 from './modules/module1.js'  // 引入module1

export default {
    state,
    getters,
    mutations,
    actions,
    modules: {
        module1  // 註冊完成
    }
}
複製代碼

在組件內打印state。vuex

console.log(this.$store.state)
複製代碼

如圖 bash

Alt text

由上圖,能夠看到,module1已經被咱們添加到了當前的store.state內;

須要注意的ide

  1. Vuex在組件中computed中使用的時候,計算屬性不能和state的數據項同名(同名了也不會報錯,就是獲取不了數據了)
  2. 有一點值得注意的是:當咱們在組件的計算屬性中使用module裏面的getters的時候,計算屬性不和state的數據項同名這條規則貌似不生效,具體緣由還不知道,若是有知道的大佬幫忙指點一下
  3. 默認狀況下,沒有設置命名空間的時候,模塊內部的 action、mutation 和 getter 是(除了state)註冊在全局命名空間的(若是有重名就會報錯 [vuex] duplicate getter key: [method])——這樣使得多個模塊可以對同一 mutation 或 action 做出響應。

解決方法是加命名空間 namespaced: trueui

如何在頁面裏面引用modulethis

  1. 在modules內的每一個模塊加入命名空間
namespaced: true
複製代碼

在vue文件內也能夠這樣spa

import { createNamespacedHelpers } from 'vuex'
const { mapState, mapActions } = createNamespacedHelpers('mudole1')
複製代碼
  1. 註冊到組件中
import { mapState, mapMutations } from "vuex"
computed: {
    ...mapState('module1', {
        width: state => state.width,  // 關聯, 此處的state 爲 module1/state
        height: state => state.height
    })
    },
methods: {
    ...mapMutations('module1', {  // 命名空間module1
        widthAdd: 'WIDTH_ADD',  // 經過mutation-types.js
        addHeight: 'addHeight'  // 直接加在mutations上面的方法
    }),
}
複製代碼
  1. 註冊完成,使用
created() {
    this.widthAdd()   // 將 `this.widthAdd()` 映射爲 `this.$store.commit('module1/widthadd')`
    console.log(this.width)  // this.width已經變爲commit之後的值
}
複製代碼

如何在模塊中訪問全局內容?

若是你但願使用全局 state 和 getter,rootState 和 rootGetter 會做爲第三和第四參數傳入 getter,也會經過 context 對象的屬性傳入 action。

若須要在全局命名空間內分發 action 或提交 mutation,將 { root: true } 做爲第三參數傳給 dispatch 或 commit 便可。
其實這塊,做者在文檔中已經說明的很清楚了,具體的連接: 詳細連接

劃分模塊的好處

  • state更爲容易管理,尤爲在團隊人數多的時候,本身負責本身的state,既保證store了完整的狀態樹,又避免了相互之間的state衝突
  • 無論是命名,或是操做 state 都會變得更加扁平和直觀
相關文章
相關標籤/搜索