目录
在上一章 <Vue前端项目-首页-获取角色> 后, 接着介绍
登陆完成后, 发生重定向, 被前端路由导航拦截, 发起异步请求获取登陆用户的角色信息(已完成)后继续获取该用户拥有的路由, 并将路由存入到 vuex 的 stores 中
前端部分
1、路由导航守卫
异步发起请求, 获取路由信息
// 挂载前端路由导航
router.beforeEach((to, from, next) => {
if (getToken()) {
if (to.path === '/login') {
next({ path: '/' })
} else {
if (store.getters.roles.length === 0) {
// 判断当前用户是否已拉取完user_info信息
store.dispatch('GetInfo').then(res => {
// 拉取user_info
const roles = res.roles
store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => {
// 测试 默认静态页面
// store.dispatch('permission/generateRoutes', { roles }).then(accessRoutes => {
// 根据roles权限生成可访问的路由表
// this.$router.options.routes = accessRoutes
router.options.routes = router.options.routes.concat(accessRoutes)
router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
}).catch(err => {
console.log(err)
})
}
next()
}
} else {
// 没有 token
if (whiteList.indexOf(to.path) !== -1) {
// 在免登陆白名单, 直接进入
next()
}
next(`/login?redirect=${to.path}`)
}
})
2、store中添加 permission模块
src / store / index.js 文件, 导入 permission模块, 并添加到 store的模块中
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import getters from './getters'
import permission from './modules/permission'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
user,
permission
},
getters
})
3、路由模块
新建 src / store / modules / permission.js 文件
import router from '@/router'
import { getRouters } from '@/api/menu'
import Layout from '@/layout/index'
const permission = {
state: {
routes: [],
addRoutes: []
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = router.options.routes.concat(routes)
}
},
actions: {
// 生成路由
GenerateRoutes({ commit }) {
return new Promise(resolve => {
// 向后端请求路由数据
getRouters().then(res => {
const accessedRoutes = filterAsyncRouter(res.data)
accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
})
}
}
}
// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap) {
return asyncRouterMap.filter(route => {
if (route.component) {
// Layout组件特殊处理
if (route.component === 'Layout') {
route.component = Layout
} else {
route.component = loadView(route.component)
}
}
if (route.children != null && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children)
}
return true
})
}
export const loadView = (view) => { // 路由懒加载
// return () => import(`@/views/${view}`) 这种写法会误报: eslint Cannot read property 'range' of null
return () => import('@/views/' + view)
}
export default permission
4、路由API
新建 src / api / menu.js 文件
import request from '@/utils/request'
// 获取路由
export const getRouters = () => {
return request({
url: '/getRouters',
method: 'get'
})
}
SpringBoot后端
1、Controller层
package com.ruoyi.project.system.controller;
/**
* 登录验证
*
* @author ruoyi
*/
@RestController
@CrossOrigin
public class SysLoginController {
@Resource
private SysLoginService loginService;
@Resource
private ISysMenuService menuService;
@Resource
private SysPermissionService permissionService;
@Resource
private TokenService tokenService;
/**
* 获取路由信息
*
* @return 路由信息
*/
@