为什么要使用 vuex 的模块化
- 由于使用单一状态树 state,应用的所有状态会集中到一个比较大的对象;
- 当应用变得非常复杂时,store 对象就有可能变得相当臃肿;
解决上面的问题
为了解决以上问题,Vuex 允许将 store 分割成模块,每个模块拥有自己的 state、mutation、action、getter 甚至是嵌套子模块——从上至下进行同样方式的分割;
示例代码
const moduleA = {
namespaced: true,
state: () => ({ ... }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
namespaced: true,
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = new Vuex.Store({
modules: {
room: moduleA,
user: moduleB
}
})
// 子模块的名字不能和父模块中的状态重名
store.state.room.xx // -> moduleA 的状态
store.state.user.xx // -> moduleB 的状态
...mapState('room', { ... }),
案例
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const rootModule = {
state: {},
mutations: {},
actions: {},
modules: {}
}
// 通过 require.context() 动态加载模块,实现 store 的状态分割
const files = require.context('./modules/', false, /\.js$/);
files.keys().forEach((key, index) => {
let store = files(key).default;
const moduleName = key.replace(/^\.\//, '').replace(/\.js$/, '');
const modules = rootModule.modules || {};
modules[moduleName] = store;
modules[moduleName].namespaced = true;
rootModule.modules = modules
});
const store = new Vuex.Store(rootModule);
export default store;
模块动态注册
-
在 store 创建之后,你可以使用 store.registerModule 方法注册模块:
import { createStore } from 'vuex' const store = createStore({ /* 选项 */ }) // 注册模块 `myModule` store.registerModule('myModule', { // ... }) // 注册嵌套模块 `nested/myModule` store.registerModule(['nested', 'myModule'], { // ... })
-
之后就可以通过 store.state.myModule 和 store.state.nested.myModule 访问模块的状态;
-
模块动态注册功能使得其他 Vue 插件可以通过在 store 中附加新模块的方式来使用 Vuex 管理状态;例如,vuex-router-sync 插件就是通过动态注册模块将 Vue Router 和 Vuex 结合在一起,实现应用的路由状态管理;
-
也可以使用 store.unregisterModule(moduleName) 来动态卸载模块;注意,不能使用此方法卸载静态模块(即创建 store 时声明的模块);
-
注意,可以通过 store.hasModule(moduleName) 方法检查该模块是否已经被注册到 store;需要记住的是,嵌套模块应该以数组形式传递给 registerModule 和 hasModule,而不是以路径字符串的形式传递给 module;
webpack 核心功能👉 入口和出口
上一篇