路由模块非常重要,自己基于这个框架进行开发,这个必须吃透!!
前情回顾:
vue-element-admin项目学习笔记(1)安装、配置、启动项目
vue-element-admin项目学习笔记(2)main.js
文件分析
vue-element-admin项目学习笔记(3)路由分析一:静态路由
如果对vue路由部分还不是很熟悉的小伙伴,建议可以先去了解一下,或者看一下我的这两篇笔记:
Vue路由简明实操笔记
vue路由守卫简明操作笔记
开始~~
文件:项目目录/src/router/index.js
1、动态路由分析
在项目目录/src/router/index.js
文件里,代码export const asyncRoutes
开始的部分的整个结构体,就是动态路由部分。
- 这部分定义的
asyncRoutes
,就是动态路由,用户可用路由条数,是计算出来的 - 然后将计算出来的当前用户路由,渲染到菜单栏上
permission.js
进行鉴权计算的,在main.js
中引用了的- 权限:页面级、路由器权限:不同权限的用户,登录进来,看到的侧边栏是不一样的、不同页面
- 区分用户可访问的范围
// 这部分定义的asyncRoutes,就是动态路由,用户可用路由条数,是计算出来的
// 然后将计算出来的当前用户路由,渲染到菜单栏上
// permission.js进行鉴权计算的,在main.js中引用了的
// 权限:页面级、路由器权限:不同权限的用户,登录进来,看到的侧边栏是不一样的、不同页面
// 区分用户可访问的范围
export const asyncRoutes = [{path: '/permission',//访问路径component: Layout,//放置一个layout组件redirect: '/permission/page',// 重定向到了自己的二级路由,在下面有配置alwaysShow: true, // 在根菜单中显示name: 'Permission',meta: { //路由元信息title: 'permission',//菜单中标题icon: 'lock',//菜单中图标// 权限就是靠roles区分的 //本项目就两个角色:admin、editor,可根据自己实际调整roles: ['admin', 'editor'] // 可见的角色,数组},children: [{//二级路由的path不要带‘/’path: 'page',//二级路由路径,完整:/permission/pagecomponent: () => import('@/views/permission/page'),//对应组件name: 'PagePermission',//路由名字meta: {title: 'pagePermission',//标题roles: ['admin'] // 可访问、可见的角色}},{path: 'directive',component: () => import('@/views/permission/directive'),name: 'DirectivePermission',meta: {title: 'directivePermission'// 二级路由权限,必须大于等于一级路由权限// 如:一级路由admin可访问、二级设置editor可访问// edtior根本没有机会看到二级// 如果不设置角色roles,则表示:此页面不需要权限校验}},{path: 'role',component: () => import('@/views/permission/role'),name: 'RolePermission',meta: {title: 'rolePermission',roles: ['admin']}}]},{path: '/icon',component: Layout,children: [{path: 'index',component: () => import('@/views/icons/index'),name: 'Icons',meta: { title: 'icons', icon: 'icon', noCache: true }}]},
2、permission.js鉴权逻辑分析
在项目目录/src/permission.js
文件里
该文件详细处理了鉴权过程的全部逻辑,非常重要
先看看流程图:
对比流程图,看代码分析
// 引入vue
import router from './router'
// 引入vuex仓库
import store from './store'
// 引入element-ui的提示组件
import { Message } from 'element-ui'
// 引入进度条、进度条风格
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
// 引入从cookie中获取 Token工具,登录后,token在cookie中
import { getToken } from '@/utils/auth'
// 引入从 获取title工具,用于切换的时候,titile变化
import getPageTitle from '@/utils/get-page-title'
// 配置进度条
NProgress.configure({ showSpinner: false })
// 配置白名单:登录页面(不需要登录即可访问)
const whiteList = ['/login', '/auth-redirect']
// 全局前置路由守卫,核心逻辑都在守卫中
router.beforeEach(async(to, from, next) => {// 开始进度条NProgress.start()//设置页面标题document.title = getPageTitle(to.meta.title)// 从cookie中获取tokenconst hasToken = getToken()// 如果有token 说明已经登录了if (hasToken) {if (to.path === '/login') {// 如果已经登录,又访问了登录页next({ path: '/' })//定向放行到后台首页面NProgress.done() //进度条结束} else {//你登录了,你去的除了登录页之外的页面// 在vuex中的仓库store中看你的权限(存在,且不为空)const hasRoles = store.getters.roles && store.getters.roles.length > 0if (hasRoles) { //权限roles存在,且不为空next() //放行} else { //如果没有角色信息,比如刷新了浏览器try {//用vuex发起获取用户信息请求const { roles } = await store.dispatch('user/getInfo')// 用获取到的用户信息中的权限,传入VUEX方法,生成路由规则const accessRoutes = await store.dispatch('permission/generateRoutes', roles)// console.log("accessRoutes",accessRoutes)// 将生成的当前用户的路由规则,添加到路由器,addRoutes方法,在user.js中router.addRoutes(accessRoutes)// 放行next({ ...to, replace: true })} catch (error) {// 获取权限过程异常,就清除登录状态await store.dispatch('user/resetToken')// 提示错误Message.error(error || 'Has Error')// 跳转到登录页面next(`/login?redirect=${to.path}`)NProgress.done()//进度条结束}}}} else {//如果没有token// 你访问的路径是不是白名单路径if (whiteList.indexOf(to.path) !== -1) {// 是白名单,就放行next()} else {// 如果不在白名单,就跳转登录页next(`/login?redirect=${to.path}`)NProgress.done()//进度条结束}}
})
// 全局后置路由守卫,就干了一件事,结束进度条
router.afterEach(() => {// finish progress barNProgress.done()
})
根据 获取到的用户信息中的权限,传入VUEX方法,生成路由规则,打印结果:
点击登录,发了两次请求:
第一次:先发登录请求,校验用户名密码,成功的话,返回token
第二次:用token,获取用户信息(权限、用户名、头像等等)