路由和权限校验
Vue的中后台系统中会有对路由和权限进行配置,学习一波 vue-admin-element 中路由配置 。
git地址 : https://github.com/PanJiaChen/vue-element-admin
路由的处理逻辑分析
中后台路由场景分析
输入一串地址 -> /xxx
- Cookie 中未存 Token 时:
- 访问为 /login 时,直接访问 /login
- 访问为 /login 以外的路由:如 /dashboard 实际访问路径为 /login?redirect=%2Fdashboard ,登录后直接重定向到 /dashboard
- Cookie 中获取到 Token 时:
- 访问为 /login 时, login 在白名单中,重定向到 / -> /dashboard
- 访问为 /login?redirect=/xxx 时,重定向到 /xxx
- 访问为 /xxx 时,直接访问为 /xxx
路由逻辑源码
第一步:在main.js 中加载了全局路由守卫
1 import './permission' // 全局路由守卫
第二步:permission.js 中定义了全局路由守卫
1 router.beforeEach(async(to, from, next) => { 2 // 启动进度条 3 NProgress.start() 4 5 // 修改页面标题 6 document.title = getPageTitle(to.meta.title) 7 8 // 从 Cookie 获取 Token 9 const hasToken = getToken() 10 11 // 判断 Token 是否存在 12 if (hasToken) { 13 if (to.path === '/login') { 14 // 如果当前路径为 login 就重定向到首页 15 next({ path: '/' }) 16 NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939 17 } else { 18 // 判断用户的角色是否存在 19 const hasRoles = store.getters.roles && store.getters.roles.length > 0 20 // 如果用户的角色存在,则直接访问 21 if (hasRoles) { 22 next() 23 } else { 24 // 如果用户的角色不存在 25 try { 26 // get user info 27 // note: roles must be a object array! such as: ['admin'] or ,['developer','editor'] 28 // 异步获取用户的角色 29 const { roles } = await store.dispatch('user/getInfo') 30 31 // generate accessible routes map based on roles 32 // 根据传入的用户角色信息,动态生成路由 33 const accessRoutes = await store.dispatch('permission/generateRoutes', roles) 34 35 // dynamically add accessible routes 36 // 调用 router.addRoutes 动态添加路由 37 router.addRoutes(accessRoutes) 38 39 // 使用 replace 访问路由,不会在 history 中留下记录 40 next({ ...to, replace: true }) 41 } catch (error) { 42 // 当获取用户 角色 和 获取路由 过程中产生异常时进行 catch 异常处理 43 // remove token and go to login page to re-login 44 // 移除 Token 数据 45 await store.dispatch('user/resetToken') 46 // 显示提示错误 47 Message.error(error || 'Has Error') 48 // 重定向到 login 页面 49 next(`/login?redirect=${to.path}`) 50 // 停止进度条 51 NProgress.done() 52 } 53 } 54 } 55 } else { 56 /* 不存在 token*/ 57 // 判断访问的 URL 是否在白名单中 58 if (whiteList.indexOf(to.path) !== -1) { 59 // in the free login whitelist, go directly 60 next() 61 } else { 62 // 如果访问的 URL 不在白名单中,则直接重定向到登录页面,并将访问的 URL 添加到 redirect 参数中 63 next(`/login?redirect=${to.path}`) 64 NProgress.done() 65 } 66 } 67 })
Tip:吃水不忘打井人 - > [小慕读书] 管理后台