小爱ADMIN系列文章二用Vuecli3mockjs-实现后台管理权限和三级菜单功能
最近完成了我的小爱ADMIN后台管理系统基本功能,同时进行了页面整体布局和样式的全新改版。新增了系统权限功能的实现,同时觉得后台系统所有的菜单都左置,会限制菜单的扩展,因此我改进了三级菜单的显示。 效果演示地址github地址权限功能的实现权限路由思路:根据用户登录的roles信息与路由中配置的roles信息进行比较过滤,生成可以访问的路由表,并通过router.addRoutes(store.getters.addRouters)动态添加可访问权限路由表,从而实现左侧和顶栏菜单的展示。 权限功能的实现步骤:1.给相应的菜单设置默认的roles信息在router/index.js中,给相应的菜单设置默认的roles信息;如下: 给"权限设置"菜单设置的权限为: { path: '/permission', name: 'permission', meta: { title: '权限设置', roles: ['admin', 'editor'] //不同的角色都可以看到 }}给其子菜单"页面权限",设置权限为: { path: 'page', name: 'pagePer', meta: { title: '页面权限', roles: ['admin'] //只有"admin"可以看到该菜单 }, component: () => import('@/page/permission/page'),}给其子菜单"按钮权限"设置权限为: { path: 'directive', name: 'directivePer', meta: { title: '按钮权限', roles:['editor'] //只有"editor"可以看到该菜单 }, component: () => import('@/page/permission/directive'),}2.通过router.beforeEach()进行路由过滤和权限拦截;代码如下: function hasPermission(roles, permissionRoles) { if (roles.indexOf('admin') >= 0) return true if (!permissionRoles) return true return roles.some(role => permissionRoles.indexOf(role) >= 0)}const whiteList = ['/login'] // 不重定向白名单router.beforeEach((to, from, next) => { NProgress.start() // 设置浏览器头部标题 const browserHeaderTitle = to.meta.title store.commit('SET_BROWSERHEADERTITLE', { browserHeaderTitle: browserHeaderTitle }) // 点击登录时,拿到了token并存入了cookie,保证页面刷新时,始终可以拿到token if (getToken('Token')) { if(to.path === '/login') { next({ path: '/' }) NProgress.done() } else { // 用户登录成功之后,每次点击路由都进行了角色的判断; if (store.getters.roles.length === 0) { let token = getToken('Token'); getUserInfo({"token":token}).then().then(res => { // 根据token拉取用户信息 let userList = res.data.userList; store.commit("SET_ROLES",userList.roles); store.commit("SET_NAME",userList.name); store.commit("SET_AVATAR",userList.avatar); store.dispatch('GenerateRoutes', { "roles":userList.roles }).then(() => { // 根据roles权限生成可访问的路由表 router.addRoutes(store.getters.addRouters) // 动态添加可访问权限路由表 next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 }) }).catch((err) => { store.dispatch('LogOut').then(() => { Message.error(err || 'Verification failed, please login again') next({ path: '/' }) }) }) } else { // 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓ if (hasPermission(store.getters.roles, to.meta.roles)) { next()// } else { next({ path: '/401', replace: true, query: { noGoBack: true }}) } } } } else { if (whiteList.indexOf(to.path) !== -1) { // 点击退出时,会定位到这里 next() } else { next('/login') NProgress.done() } }})router.afterEach(() => { NProgress.done() // 结束Progress setTimeout(() => { const browserHeaderTitle = store.getters.browserHeaderTitle setTitle(browserHeaderTitle) }, 0)})本系统权限逻辑分析1、路由对象区分权限路由对象和非权限路由对象;初始化时,将非权限路由对象赋值给Router;同时设置权限路由中的meta对象,如:meta:{roles:['admin','editor']},表示该roles所拥有的路由权限; ...