[vue-element-admin] 一、权限路由的初始化分析

这里的权限只是局限于前端,只用来控制用户角色在登陆后应当显示哪些菜单,真正的权限校验配置还会在后端维护一套路由表(这里官方文档说是为了摆脱前后端耦合的支配,我觉得没必要,这个可以在开发之前先让后端开发路由增删查改接口,直接暴露给前端配置,应该耗不了多长时间,这样前端只要post个json到后端就可以完成配置。用户的惯性思维是我能看到就应当可以操作,不管是从安全的角度还是用户体验的角度, 权限都理应由后端统一控制。)。

※阅读时主要关注注释点。本文主要记录作者分析过程发现的关键点,如需详细教程请移步Github上的官方文档。
本文基于4.2.1版本国际化分支 i18n Branch代码做分析
(主干在版本v4.1.0之后已不再支持国际化,但仍会保持与主干同步更新该分支。
After the v4.1.0+ version,the default master branch will not support i18n.Please use i18n Branch, it will keep up with the master update)。

1.没登陆之前

没登陆之前只挂载不需要权限的路由,比如login之类的

1.1、main.js引入router.js

import router from './router' //这里其实只挂载了不需要权限的路由
new Vue({
  el: '#app',
  router,
  store,
  i18n,
  render: h => h(App)
})

1.2、非权限路由挂载(router.js)

export const constantRoutes = [
  {
    path: '/redirect',
    component: Layout,
    hidden: true,
    children: [
      {
        path: '/redirect/:path*',
        component: () => import('@/views/redirect/index')
      }
    ]
  },
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  }]
//创建路由实例  
const createRouter = () => new Router({
  // mode: 'history', // require service support
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRoutes //不需要权限的路由
})
//初始化路由实例  
const router = createRouter()
//导出
export default router

2.登录后

2.1、通过store中user模块下的getInfo动作获取用户角色信息

const { roles } = await store.dispatch('user/getInfo')

2.2、根据角色信息去生成动态路由列表

2.2.1、调用路由生成动作
const actions = {
    ......
    //获取权限路由
    const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
     // dynamically add accessible routes 
     //此时路由器里面只有非权限路由,现在把获取到的权限路由推入路由器
    router.addRoutes(accessRoutes)
    ......
    }
2.2.2、生成动态路由
import { asyncRoutes, constantRoutes } from '@/router' //所有路由
const actions = {
    
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
          //根据角色获取动态路由
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      //刷新当前权限路由
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
    })
  }
}
/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
    //路由中有配置meta.roles才会进入权限过滤
  if (route.meta && route.meta.roles) {
      //判断这个路由的meta.roles角色列表是否包含当前角色
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}
/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    //判断当前角色是否有该路由的权限
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      //把有权限的路由推入动态列表
      res.push(tmp)
    }
  })

  return res
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值