【Vue】 vue-element-admin 路由菜单配置
路由说明见官方文档:
https://panjiachen.gitee.io/vue-element-admin-site/zh/guide/essentials/router-and-nav.html
组件渲染的数据来源
这里先说明侧边栏组件获取的路由:
src\layout\components\Sidebar\index.vue
路由是通过这个permission_routers获取的
<template>
<div :class="{'has-logo':showLogo}">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
:background-color="variables.menuBg"
:text-color="variables.menuText"
:unique-opened="false"
:active-text-color="variables.menuActiveText"
:collapse-transition="false"
mode="vertical"
>
<sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" />
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/styles/variables.scss'
export default {
components: { SidebarItem, Logo },
computed: {
...mapGetters([
'permission_routes',
'sidebar'
]),
activeMenu() {
const route = this.$route
const { meta, path } = route
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu
}
return path
},
showLogo() {
return this.$store.state.settings.sidebarLogo
},
variables() {
return variables
},
isCollapse() {
return !this.sidebar.opened
}
}
}
</script>
访问到Gettter.js可以看到Vuex是区分了命名空间的,对应的空间是permission
const getters = {
sidebar: state => state.app.sidebar,
size: state => state.app.size,
device: state => state.app.device,
visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
introduction: state => state.user.introduction,
roles: state => state.user.roles,
// permission_routes: state => state.permission.routes,
permission_routes: state => state.menu.routes,
errorLogs: state => state.errorLog.logs
}
export default getters
所以说,默认是从permission模块里的routes获取的
如果我们新开的Vuex写路由获取逻辑,这里不改的话就拿不到我们自己获取的路由了
路由权限控制
在main.js下面的permission里面:
每次跳转路由,都要从VueX拿令牌,判断用户是否有效
自己定义校验规则 和 路由获取规则即可,
这段参考Open-his来做的,路由还是前端配置,控制只展示哪些,交给后端来完成
import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
/**
* no redirect whitelist
* 白名单,没有权限控制的路由地址
* @type {string[]}
*/
const whiteList = ['/login', '/auth-redirect']
/**
* 在路由跳转之前,勾子函数的控制
*/
router.beforeEach(async(to, from, next) => {
/* 启动进度条 start progress bar */
NProgress.start()
/* 设置系统标签文本信息 set page title */
document.title = getPageTitle(to.meta.title)
/* 从Cookie里面提取令牌 determine whether the user has logged in */
const hasToken = getToken()
/* 令牌存在 */
if (hasToken) {
/* 访问登录页时直接放行 */
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({ path: '/' })
NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
} else {
/**
* 判断当前用户的角色集合是否存在
* determine whether the user has obtained his permission roles through getInfo
* @type {any}
*/
// const hasRoles = store.getters.roles && store.getters.roles.length > 0
/* 存在则放行路由 */
// 确定用户是否已通过getInfo获得其用户
const hasName = !!store.getters.name
if (hasName) {
next()
} else {
/* 没有则重新获取用户信息 */
try {
/**
* // get user info
* // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
* 根据令牌重新获取用户信息,只要角色集合
*/
const { menus } = await store.dispatch('user/getInfo')
/**
* generate accessible routes map based on roles
* 创建可访问的路由表
* @type {any}
*/
// const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
const accessRoutes = await store.dispatch('menu/getAccessMenus', menus)
/**
* dynamically add accessible routes
* 动态添加路由
*/
router.addRoutes(accessRoutes)
/**
* 如果用户状态持续,保持路由不会丢掉历史记录
* // hack method to ensure that addRoutes is complete
* // set the replace: true, so the navigation will not leave a history record
*/
next({ ...to, replace: true })
} catch (error) {
/**
* 如果用户信息无法获取,重定向,要求用户重新登录
* remove token and go to login page to re-login
*/
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
}
} else {
/* 如果没有令牌,检查是否是白名单的路由 has no token*/
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
/* 没有权限,也不是白名单,重定向到登录页面 */
// other pages that do not have permission to access are redirected to the login page.
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
})
/* 每次跳转之后的回调勾子 */
router.afterEach(() => {
/* finish progress bar 进度条加载完成 */
NProgress.done()
})
路由获取规则Menu.js
import { asyncRoutes, constantRoutes, lastRoute } from '@/router/index'
const state = {
routes: []
}
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = routes
}
}
/**
* 递归路由集合,和用户的菜单进行比较,符合则打开,反之关闭
* @param routes
* @param srvMenus
*/
function generateMenus(routes, srvMenus) {
for (let i = 0; i < routes.length; i++) {
const routeItem = routes[i]
let showItem = false
for (let j = 0; j < srvMenus.length; j++) {
const srvItem = srvMenus[j]
// 前后端数据通过 serPath 属性来匹配
if (routeItem.name !== undefined && routeItem.name === srvItem['menuRoute'] && srvItem['isShow'] === true) {
showItem = true
routes[i]['hidden'] = false
break
}
}
if (showItem === false) {
routes[i]['hidden'] = true
}
if (routeItem['children'] !== undefined && routeItem['children'].length > 0) {
generateMenus(routes[i]['children'], srvMenus)
}
}
}
const actions = {
getAccessMenus({ commit }, menus) {
return new Promise(resolve => {
const pushRouter = asyncRoutes
generateMenus(pushRouter, menus)
const routeArr = []
console.log(constantRoutes)
routeArr.push(...constantRoutes)
routeArr.push(...pushRouter)
routeArr.push(...lastRoute)
commit('SET_ROUTES', routeArr)
console.log(routeArr)
/* 返回全部匹配的路由 */
resolve(routeArr)
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
前端路由表配置:
我想弄三层菜单,需要第二层再单开组件放路由才可以,这个可以查看文档说明
https://panjiachen.github.io/vue-element-admin-site/zh/guide/essentials/router-and-nav.html#侧边栏

这里我就只放异步路由的配置,常量路由是所有人都能看的,没啥可表达的
/**
* 异步路由,根据用户的角色集合动态加载
* asyncRoutes
* the routes that need to be dynamically loaded based on user roles
*/
export const asyncRoutes = [
{
path: '/system',
component: Layout,
redirect: 'noRedirect',
name: '/system',
alwaysShow: true,
meta: { title: '系统管理', icon: 'lock' },
children: [
{
path: 'rbac',
component: () => import('@/views/tt-server/system/rbac/index'),
name: '/system/rbac',
meta: { title: '权限维护', icon: 'lock' },
children: [
{
path: 'user-info',
component: () => import('@/views/tt-server/system/rbac/user-info/index'),
name: '/system/rbac/user-info',
meta: { title: '用户管理', icon: 'edit' }
},
{
path: 'role-info',
component: () => import('@/views/tt-server/system/rbac/role-info/index'),
name: '/system/rbac/role-info',
meta: { title: '角色管理', icon: 'edit' }
},
{
path: 'menu-info',
component: () => import('@/views/tt-server/system/rbac/menu-info/index'),
name: '/system/rbac/menu-info',
meta: { title: '菜单管理', icon: 'edit' }
},
{
path: 'privilege-info',
component: () => import('@/views/tt-server/system/rbac/privilege-info/index'),
name: '/system/rbac/privilege-info',
meta: { title: '权限管理', icon: 'edit' }
}
]
},
{
path: 'common',
component: () => import('@/views/tt-server/system/common/index'),
name: '/system/common',
alwaysShow: true,
meta: { title: '通用管理', icon: 'lock' },
children: [
{
path: 'dict-info',
component: () => import('@/views/tt-server/system/common/dict-info/index'),
name: '/system/common/dict-info',
meta: { title: '字典管理', icon: 'edit' }
},
{
path: 'area-info',
component: () => import('@/views/tt-server/system/common/area-info/index'),
name: '/system/common/area-info',
meta: { title: '区域管理', icon: 'edit' }
},
{
path: 'system-param',
component: () => import('@/views/tt-server/system/common/system-param/index'),
name: '/system/common/system-param',
meta: { title: '系统参数', icon: 'edit' }
},
{
path: 'system-log',
component: () => import('@/views/tt-server/system/common/system-log/index'),
name: '/system/common/system-log',
meta: { title: '系统日志', icon: 'edit' }
}
]
}
]
}
]
后台数据设计:
表结构
CREATE TABLE `sys_menu` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '菜单主键', `app_code` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '应用编号', `menu_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '菜单名称', `menu_value` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '菜单值', `menu_icon` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '菜单图标', `menu_level` int NOT NULL DEFAULT '1' COMMENT '菜单层级', `menu_type` varchar(12) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '菜单类型', `menu_sort` int NOT NULL COMMENT '菜单排序', `menu_route` varchar(64) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '菜单路由', `is_show` tinyint(1) DEFAULT '1' COMMENT '是否展示 1展示 0隐藏', `menu_path` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '菜单主键路径', `parent_id` int NOT NULL DEFAULT '0' COMMENT '父级菜单,顶级菜单默认为0', `creator` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建人', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `updater` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '更新人', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=100200401 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='系统菜单表';
菜单记录:
【菜单路由】和【是否展示】是前端路由展示的判断条件
mysql> SELECT * FROM sys_menu; +-----------+-----------+-----------+--------------+-----------+------------+-----------+-----------+-----------------------------+---------+---------------------------------+-----------+---------+---------------------+---------+---------------------+ | id | app_code | menu_name | menu_value | menu_icon | menu_level | menu_type | menu_sort | menu_route | is_show | menu_path | parent_id | creator | create_time | updater | update_time | +-----------+-----------+-----------+--------------+-----------+------------+-----------+-----------+-----------------------------+---------+---------------------------------+-----------+---------+---------------------+---------+---------------------+ | 100000000 | tt-server | 系统管理 | system | | 1 | Directory | 1 | /system | 1 | 0,100000000 | 0 | admin | 2022-12-07 23:46:49 | admin | 2022-12-07 23:46:51 | | 100100000 | tt-server | 权限维护 | privileges | | 2 | Directory | 1 | /system/rbac | 1 | 0,100000000,100100000 | 100000000 | admin | 2022-12-07 23:41:14 | admin | 2022-12-07 23:41:16 | | 100100100 | tt-server | 用户管理 | user-info | | 3 | Function | 1 | /system/rbac/user-info | 1 | 0,100000000,100100000,100100100 | 100100000 | admin | 2022-12-07 23:44:12 | admin | 2022-12-07 23:44:12 | | 100100200 | tt-server | 角色管理 | role-info | | 3 | Function | 2 | /system/rbac/role-info | 1 | 0,100000000,100100000,100100200 | 100100000 | admin | 2022-12-07 23:44:12 | admin | 2022-12-07 23:44:12 | | 100100300 | tt-server | 菜单管理 | menu-info | | 3 | Function | 3 | /system/rbac/menu-info | 1 | 0,100000000,100100000,100100300 | 100100000 | admin | 2022-12-07 23:44:12 | admin | 2022-12-07 23:44:12 | | 100100400 | tt-server | 权限管理 | permit-info | | 3 | Function | 4 | /system/rbac/privilege-info | 1 | 0,100000000,100100000,100100400 | 100100000 | admin | 2022-12-07 23:44:12 | admin | 2022-12-07 23:44:12 | | 100200000 | tt-server | 通用管理 | common | | 2 | Directory | 2 | /system/common | 1 | 0,100000000,100200000 | 100000000 | admin | 2022-12-07 23:42:03 | admin | 2022-12-07 23:42:03 | | 100200100 | tt-server | 字典管理 | dict-info | | 3 | Function | 1 | /system/common/dict-info | 1 | 0,100000000,100200000,100200100 | 100200000 | admin | 2022-12-07 23:44:12 | admin | 2022-12-07 23:44:12 | | 100200200 | tt-server | 行政区域 | area-info | | 3 | Function | 2 | /system/common/area-info | 1 | 0,100000000,100200000,100200200 | 100200000 | admin | 2022-12-07 23:44:12 | admin | 2022-12-07 23:44:12 | | 100200300 | tt-server | 系统参数 | system-param | | 3 | Function | 3 | /system/common/system-param | 1 | 0,100000000,100200000,100200300 | 100200000 | admin | 2022-12-07 23:44:12 | admin | 2022-12-07 23:44:12 | | 100200400 | tt-server | 系统日志 | system-log | | 3 | Function | 4 | /system/common/system-log | 1 | 0,100000000,100200000,100200400 | 100200000 | admin | 2022-12-07 23:44:12 | admin | 2022-12-07 23:44:12 | +-----------+-----------+-----------+--------------+-----------+------------+-----------+-----------+-----------------------------+---------+---------------------------------+-----------+---------+---------------------+---------+---------------------+
展示效果


浙公网安备 33010602011771号