后台管理系统动态路由菜单
后台管理系统权限管控+动态路由菜单
最近在做后台管理系统权限,因此在此做下笔记,仅当记录巩固用
思路:动态路由首先需要在用户登入的时候请求路由菜单,然后前端存起来(可以存浏览器,也可以存仓库),然后经过过滤形成完整的路由菜单
环境:vue2.0 关于为什么不用vue3呢,是当时草率的选了element-ui,其实还可以用别的ui库:如vuetify、storybook、ionic-framework
首先在跟main.js同级建立一个permission.js文件用作路由过滤,然后在main.js中引入:
import ‘./permission’
在permission.js中使用 nprogress 插件做加载进度展示
然后将router,store,ngrogress,token,menuApi等引入进来
在路由前置守卫钩子做相应逻辑处理
//白名单列表
const whiteList =['','']
//to:即将路由的地址
//form:当前的路由地址,也是马上要离开的地址
//next:执行进入的下一个路由
router.beforeEach((to,from,next)=>{
//如果需要重新定义标题名字
if(to.meta.title){
document.title = to.meta.title + '-' +'...'
}
NProgress.start()
//再进行有没有token的判断,有token直接进入,没token则跳转到登录页面
if(token){
//还需要做跳转的判断,是进入登录页面还是其他页面,如果不是登录页面还需要判断用户信息是否已经拉取完毕,
//还有菜单是否拉取
if(to.path =='/login'){
next()
NProgress.done()
}else{
if('用户信息是否已经拉取完,详情视实际情况做判断'){
//没拉去在此处拉去用户信息,之后请求菜单列表,请求菜单并加工菜单loadMenus(next,to)
}
if('如果登录了菜单没拉到,在此处拉去'){
//调用菜单获取方法
}
next()
}
}else{
//如果有设置有白名单列表,可直接进入,否则重定向到登录页
if(whiteList.indexOf(to.path) !=-1){
next()
}else{
next(`/login?redirect=${to.path}`)
}
}
})
我这边后台返回的数据格式是这样子的
然后后台返回的菜单列表我是存放在store里面,我们主要的目的是要将后台返回的菜单列表中的component加工成 component:() => import(’@/views/login/login.vue’) 这种类型的格式
const asyncRouter = filterAsyncRouter(res.data.data.treeData)
store.dispatch('GenerateRouters',asyncRouter).then(()=>{
//存储路由 动态添加可访问路由表
router.addRoutes(asyncRouter)
next({...to,replace:true})
})
//store中的filterAsyncTouter
export const filterAsyncRouter = routes =>{
//遍历后台的路由字符串,转换为组件对象
const accessedRouters = routes.filter(router =>{
if(router.component) {
if(router.component ==='Layout'){
//Layout组件特殊处理
router.component = Layout## 标题
}else {
const component = router.component
router.component = loadView(component)
}
}
//如果下一层还有children,再次使用递归遍历
if( router.children && router.children.length && router.children !=null){
router.children = filterAsyncRouter(router.children)
}
return true
})
return accessedRouters
}
export const loadView = view =>{
return () => import(`@/views/${view}`)
}
//GenerateRouters 需要添加到路由中的路由 store文件中
import {constantRoutes} from '../../router'
const permission ={
state:{
routes:constantRoutes,
addRouters:[]
},
mutations:{
SET_ROUTERS:(state,routes) =>{
state.addRouters = routes,
state.routes = routes //左侧菜单栏光展示后端给的路由
// routes 为动态路由 ,将后台给的路由菜单跟写在router文件中的路由菜单同步展示在左侧菜单栏
// state.routes = constantRoutes.concat(routes)
}
},