模块注册 #
静态注册 vs 动态注册 #
静态注册 #
在创建 store 时注册模块:
javascript
const store = createStore({
modules: {
user: userModule,
cart: cartModule
}
})
动态注册 #
在 store 创建后注册模块:
javascript
// 创建 store
const store = createStore({})
// 动态注册模块
store.registerModule('user', userModule)
registerModule #
基本用法 #
javascript
// 注册单个模块
store.registerModule('user', {
state: () => ({
name: '',
email: ''
}),
mutations: {
SET_NAME(state, name) {
state.name = name
}
}
})
// 访问
store.state.user.name
嵌套模块 #
javascript
// 注册嵌套模块
store.registerModule(['user', 'profile'], {
state: () => ({
avatar: '',
bio: ''
})
})
// 访问
store.state.user.profile.avatar
保留状态 #
javascript
// 注册时保留已有状态
store.registerModule('user', userModule, {
preserveState: true // 保留已存在的状态
})
unregisterModule #
卸载模块 #
javascript
// 注册模块
store.registerModule('user', userModule)
// 卸载模块
store.unregisterModule('user')
// 访问会返回 undefined
store.state.user // undefined
注意事项 #
javascript
// 不能卸载静态注册的模块
const store = createStore({
modules: {
user: userModule // 静态注册
}
})
store.unregisterModule('user') // 无效
hasModule #
检查模块是否存在 #
javascript
// 检查模块是否已注册
if (store.hasModule('user')) {
console.log('User module exists')
}
// 检查嵌套模块
if (store.hasModule(['user', 'profile'])) {
console.log('User profile module exists')
}
使用场景 #
按需加载模块 #
javascript
// 路由守卫中加载模块
router.beforeEach(async (to, from, next) => {
if (to.meta.requiresAuth && !store.hasModule('auth')) {
// 动态加载认证模块
const authModule = await import('./modules/auth')
store.registerModule('auth', authModule.default)
}
next()
})
懒加载模块 #
javascript
// 组件中懒加载模块
export default {
name: 'AdminPanel',
async created() {
if (!this.$store.hasModule('admin')) {
const adminModule = await import('@/store/modules/admin')
this.$store.registerModule('admin', adminModule.default)
}
this.$store.dispatch('admin/fetchDashboard')
},
beforeUnmount() {
// 组件销毁时卸载模块
this.$store.unregisterModule('admin')
}
}
插件注册模块 #
javascript
// Vuex 插件
function createWebSocketPlugin(socket) {
return store => {
// 注册 websocket 模块
store.registerModule('websocket', {
state: () => ({
connected: false,
messages: []
}),
mutations: {
SET_CONNECTED(state, connected) {
state.connected = connected
},
ADD_MESSAGE(state, message) {
state.messages.push(message)
}
}
})
// 监听 socket 事件
socket.on('connect', () => {
store.commit('websocket/SET_CONNECTED', true)
})
socket.on('message', (message) => {
store.commit('websocket/ADD_MESSAGE', message)
})
socket.on('disconnect', () => {
store.commit('websocket/SET_CONNECTED', false)
})
}
}
// 使用插件
const store = createStore({
plugins: [createWebSocketPlugin(socket)]
})
多实例模块 #
javascript
// 创建可复用的模块工厂
function createFormModule(formId) {
return {
namespaced: true,
state: () => ({
id: formId,
values: {},
errors: {},
touched: {}
}),
mutations: {
SET_VALUE(state, { field, value }) {
state.values[field] = value
},
SET_ERROR(state, { field, error }) {
state.errors[field] = error
},
SET_TOUCHED(state, field) {
state.touched[field] = true
},
RESET(state) {
state.values = {}
state.errors = {}
state.touched = {}
}
}
}
}
// 为每个表单注册独立模块
store.registerModule(['forms', 'login'], createFormModule('login'))
store.registerModule(['forms', 'register'], createFormModule('register'))
实战示例 #
动态加载功能模块 #
javascript
// store/index.js
import { createStore } from 'vuex'
import user from './modules/user'
export default createStore({
modules: {
user // 核心模块静态加载
}
})
// store/modules/loader.js
const moduleCache = new Map()
export async function loadModule(store, moduleName) {
if (moduleCache.has(moduleName)) {
return moduleCache.get(moduleName)
}
if (store.hasModule(moduleName)) {
return
}
try {
const module = await import(`./modules/${moduleName}`)
store.registerModule(moduleName, module.default)
moduleCache.set(moduleName, module.default)
} catch (error) {
console.error(`Failed to load module: ${moduleName}`, error)
throw error
}
}
// 使用
import { loadModule } from './modules/loader'
// 路由配置
const routes = [
{
path: '/dashboard',
component: () => import('@/views/Dashboard.vue'),
meta: { module: 'dashboard' }
},
{
path: '/products',
component: () => import('@/views/Products.vue'),
meta: { module: 'products' }
}
]
// 路由守卫
router.beforeEach(async (to, from, next) => {
const moduleName = to.meta.module
if (moduleName) {
await loadModule(store, moduleName)
}
next()
})
临时模块管理 #
javascript
// composables/useTempModule.js
import { onUnmounted } from 'vue'
import { useStore } from 'vuex'
export function useTempModule(moduleName, moduleDefinition) {
const store = useStore()
// 注册模块
if (!store.hasModule(moduleName)) {
store.registerModule(moduleName, moduleDefinition)
}
// 组件卸载时清理
onUnmounted(() => {
if (store.hasModule(moduleName)) {
store.unregisterModule(moduleName)
}
})
return {
state: computed(() => store.state[moduleName]),
commit: (type, payload) => store.commit(`${moduleName}/${type}`, payload),
dispatch: (type, payload) => store.dispatch(`${moduleName}/${type}`, payload)
}
}
// 使用
export default {
setup() {
const { state, commit, dispatch } = useTempModule('tempForm', {
namespaced: true,
state: () => ({ data: null }),
mutations: { SET_DATA: (s, d) => s.data = d }
})
return { state }
}
}
条件模块注册 #
javascript
// 根据用户权限加载模块
actions: {
async initApp({ dispatch, commit }) {
// 获取用户权限
const permissions = await api.getPermissions()
commit('SET_PERMISSIONS', permissions)
// 根据权限加载模块
if (permissions.includes('admin')) {
await dispatch('loadAdminModule')
}
if (permissions.includes('reports')) {
await dispatch('loadReportsModule')
}
},
async loadAdminModule({ state }) {
if (!this.hasModule('admin')) {
const adminModule = await import('./modules/admin')
this.registerModule('admin', adminModule.default)
}
}
}
最佳实践 #
1. 模块命名规范 #
javascript
// 推荐:清晰的命名
store.registerModule('userProfile', profileModule)
store.registerModule('shoppingCart', cartModule)
// 不推荐:模糊的命名
store.registerModule('module1', someModule)
2. 检查模块是否存在 #
javascript
// 推荐:先检查再注册
if (!store.hasModule('user')) {
store.registerModule('user', userModule)
}
// 不推荐:直接注册可能覆盖
store.registerModule('user', userModule)
3. 及时清理 #
javascript
// 推荐:不再使用时卸载
onUnmounted(() => {
store.unregisterModule('tempModule')
})
// 不推荐:不清理导致内存泄漏
4. 错误处理 #
javascript
try {
if (!store.hasModule(moduleName)) {
const module = await import(`./modules/${moduleName}`)
store.registerModule(moduleName, module.default)
}
} catch (error) {
console.error(`Failed to register module: ${moduleName}`, error)
// 处理错误
}
总结 #
模块注册要点:
| 方法 | 说明 |
|---|---|
registerModule |
动态注册模块 |
unregisterModule |
卸载动态注册的模块 |
hasModule |
检查模块是否存在 |
preserveState |
注册时保留已有状态 |
继续学习 状态持久化,了解如何持久化存储状态。
最后更新:2026-03-28