1. Vuex相关设计
1.1 模块化
- 用户权限模块:
- 创建一个
userPermission
模块,用于存储用户权限相关信息,例如userRole
(用户角色,如'admin'
或'user'
)。
- 在该模块的
state
中定义权限相关状态:
const userPermission = {
namespaced: true,
state: () => ({
userRole: null
}),
mutations: {
SET_USER_ROLE(state, role) {
state.userRole = role;
}
},
actions: {
async fetchUserRole({ commit }) {
// 假设从后端获取用户角色
const response = await axios.get('/api/user/role');
commit('SET_USER_ROLE', response.data.role);
}
}
};
- 路由菜单模块:
- 创建
routeMenu
模块,用于生成和管理路由菜单。
- 在
state
中存储动态生成的路由菜单:
const routeMenu = {
namespaced: true,
state: () => ({
menus: []
}),
mutations: {
SET_ROUTE_MENUS(state, menus) {
state.menus = menus;
}
},
actions: {
generateRouteMenus({ commit, rootState }) {
const { userRole } = rootState.userPermission;
let menus = [];
if (userRole === 'admin') {
menus = [
{ path: '/admin/dashboard', name: 'Admin Dashboard' },
{ path: '/admin/users', name: 'Manage Users' }
];
} else {
menus = [
{ path: '/user/dashboard', name: 'User Dashboard' }
];
}
commit('SET_ROUTE_MENUS', menus);
}
}
};
1.2 命名空间
- 为每个模块设置
namespaced: true
,确保模块内的状态、mutations、actions等不会与其他模块冲突。例如,在userPermission
模块中,通过userPermission/SET_USER_ROLE
这样的命名空间来提交mutation,在组件中调用this.$store.commit('userPermission/SET_USER_ROLE', 'admin')
。
2. Router相关设计
2.1 导航守卫
- 全局前置守卫:
- 在
router.js
中设置全局前置守卫,用于在路由切换前检查用户权限并确保相关页面状态的正确传递和保存。
import router from './router';
import store from './store';
router.beforeEach(async (to, from, next) => {
// 确保用户角色已获取
if (!store.state.userPermission.userRole) {
await store.dispatch('userPermission/fetchUserRole');
}
const { userRole } = store.state.userPermission;
const routeMenus = store.state.routeMenu.menus;
const hasPermission = routeMenus.some(menu => menu.path === to.path);
if (hasPermission) {
// 保存当前页面状态(假设使用keep - alive,可在组件内通过activated和deactivated钩子保存和恢复状态)
if (from.name) {
// 可在此处将from页面状态保存到Vuex
}
next();
} else {
next('/403'); // 无权限时跳转到403页面
}
});
- 组件内守卫:
- 在需要特殊权限控制的组件内设置守卫,例如在
AdminDashboard.vue
组件中:
export default {
beforeRouteEnter(to, from, next) {
const { userRole } = this.$store.state.userPermission;
if (userRole === 'admin') {
next();
} else {
next('/403');
}
}
};
3. 整合Vuex和Router
- 在
main.js
中,先初始化Vuex,然后在Router设置完成后挂载Vue实例。
import Vue from 'vue';
import store from './store';
import router from './router';
new Vue({
store,
router,
render: h => h(App)
}).$mount('#app');
- 在组件中,通过
this.$store
访问Vuex状态和触发actions,通过this.$router
进行路由导航操作。例如,在App.vue
中可以通过this.$store.dispatch('routeMenu/generateRouteMenus')
生成路由菜单,并在模板中展示动态路由菜单。