前端路漫漫,挽起袖子干前端
我以前总结过动态菜单的实现方案>动态菜单实现,
只不过这篇写的有点稍微复杂,是用后端返回当前登陆角色的路由表实现的,也就是前端只要从后端取到路由表进行渲染菜单便可;vue
今天,我再讲解一种方案:路由表写在前端,后端返回用户的角色,前端进行角色对应的菜单渲染ios
在线预览:动态路由
github(记的star哈):https://github.com/Mrblackant...git
开始以前,本身要大概懂写关于vue-router的beforeEach(路由拦截)、addRoutes,elementUI的菜单组件等方法,否则理解可能会有点吃力github
分如下几步:
1.前端在本地写好路由表,以及每一个路由对应的角色,也就是哪些角色能够看到这个菜单/路由;
2.登陆的时候,向后端请求获得登陆用户的角色(管理者、普通用户);
3.利用路由拦截,根据取到的用户角色,跟本地的路由表进行对比,过滤出用户对应的路由,并利用路由进行左侧菜单渲染vue-router
根据上述的3步,咱们进行每一步的实现vuex
1.前端本地写好路由表
咱们分红两个路由表,一个是固定的,好比首页展现,每一个人都能看到,一个须要根据用户角色动态展现的;
这里就利用到了router的meta属性,咱们在这里边写上菜单对应的:icon,对应的哪些角色能够看到这个菜单:roles
一个完整的路由表以下:axios
//代码位置:router/index.js { path: '', component: layout, //总体页面的布局(包含左侧菜单跟主内容区域) children: [{ path: 'main', component: main, meta: { title: '首页', //菜单名称 roles: ['user', 'admin'], //当前菜单哪些角色能够看到 icon: 'el-icon-info' //菜单左侧的icon图标 } }] }
2.用户登陆,取到用户的角色
原本我是写了mock数据,模拟用户登陆,请求后端角色的接口,奈何mock挂了,
因此我就直接模拟了:segmentfault
取到用户角色,存放进localStorage,而后跳转主页后端
//代码位置:src/components/reLoad.vue // axios.post('/temp',this.formModel).then(res=>{}) // 我暂时就不模拟了,直接取 let getUserRole = this.formModel.user === 'admin' ? 'admin' : 'user' localStorage.setItem('userRole', getUserRole) this.$router.push({ path: '/main' })
3.路由拦截beforeEach,并过滤出角色对应的路由表
通过第2步,咱们已经获得了用户的角色,这时候在路由拦截的地方咱们就能够取到了,
取到以后,结合第1步咱们写好的路由,利用数组的filter方法,拿角色跟路由表里meta标签里的roless数据进行对比
过滤好了,拿当前路由去渲染左侧菜单,这一步其实能够用vuex去实现,我担忧有的小伙伴不理解,就用一个global(全局变量)替代了
尤为要注意路由拦截这里,很容易陷入死循环,因此我建议你们先了解一下beforeEach和addRoutes的运行机制
//代码位置:src/permission.js router.beforeEach((to, from, next) => { // 取到用户的角色 let GetRole = localStorage.getItem("userRole") // 若是登陆了 if (GetRole !== 'unload') { next() //next()方法后的代码也会执行 // 1.若是路由表 没根据角色进行筛选,就筛选一次 if (!addRouFlag) { addRouFlag = true // 2.根据用户的角色、和须要动态展现的路由,生成符合用户角色的路由 var getRoutes = baseRoleGetRouters(permissionRouter, GetRole.split(",")) // 3.利用global属性,让渲染菜单的组件sideMeuns.vue从新生成左侧菜单 global.antRouter = fixedRouter.concat(getRoutes) // 4.将生成好的路由addRoutes router.addRoutes(fixedRouter.concat(getRoutes)) // 5.push以后,会从新进入到beforeEach的钩子里,直接进入第一个if判断 router.push({ path: to.path }) } } else { // 用户没登陆,跳转到登陆页面 if (to.path === '/') { next() } else { next('/') } } })
1.根据路由进行菜单展现
代码位置:/src/components/sideMeuns.vue,
先看下elementUI菜单组件,把一些基础的参数先了解一下,
这里我把菜单渲染写成了一个组件:
用到了递归属性,保证能够生成多级菜单,
我建议不熟悉的,你们用组件先模拟着写一个包含跳转功能、icon展现的菜单,而后再看我写的组件
2.用户退出系统
代码位置:/src/components/layout.vue
退出的时候,记得清除掉存在localStorage的用户角色,
而后利用 window.location.href = "/"跳转到登陆页,
为何要用location.href,这样会把以前addRoutes的路由清除掉,确保下个用户登录后,会从新渲染正确的菜单
若是有些地方不理解,师兄建议把不理解的点先单独拿出来跑跑,
或者看看这篇文章的思路来源:手把手...
若有不正确的地方,还望小伙伴指正哈