vue-admin-template改造实现后台传入路由表动态生成权限菜单

mac2022-06-30  22

序言

因为打算做前后端分离的权限控制,并且生成动态的权限菜单,但是发现vue-admin-template是前端根据角色控制页面,并且代码写死在前端,我觉得这样不好,后面用户管理的时候添加了个角色前端就得改代码,就查阅了下资料,根据后台来传入路由表,然后再通过router.addRouters();方法将路由表添加进去;

具体

1.后台传入路由表数据数据格式
{ "message": "success", "success": true, "code": 20000, "data": { "name": "Uncle", "avatar": "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", "roles": ["admin"], "routers": [{ "name": "Test_It", "path": "/test", "component": "Layout", "children": [{ "name": "Test_It_c", "path": "index", "component": "Test", "meta": { "icon": "example", "title": "后台" }, }] }] } }
2.前端页面将json格式化成js对象,重点是将compoent转化真实的组件对象

2.1 格式化工具

import Test from '@/views/form/index' import Layout from '@/layout' export default function (routers) { return filterAsyncRouter(routers) } //将后台返回的json权限数据格式化(递归遍历子节点) export const filterAsyncRouter=(asyncRouterMap) =>{ //遍历后台传来的路由字符串,转换为组件对象 const accessedRouters = asyncRouterMap.filter(route => { if (route.component) { if (route.component === 'Layout') { //Layout组件特殊处理 route.component = Layout } else { route.component = Test } } if (route.children && route.children.length) { route.children = filterAsyncRouter(route.children) } return true }) return accessedRouters }

2.2 获取路由表并且格式化

import {constantRouterMap} from '@/router'; const user = { state: { routers: constantRouterMap, addRouters: [] }, mutations: { SET_ROUTERS: (state, routers) => { state.addRouters = routers; //路由访问 state.routers = constantRouterMap.concat(routers); //菜单显示 } }, actions: { // 获取用户信息 GetInfo({commit,state }) { return new Promise((resolve, reject) => { getInfo(state.token).then(response => { const data = response.data commit('SET_NAME', data.name) commit('SET_ROLES', data.roles) commit('SET_AVATAR', data.avatar) commit('SET_ROUTERS', routerFormat(data.routers)) resolve(response) }).catch(error => { reject(error) }) }) }, }
3.添加路由表

全局路由拦截器

import router from './router' import store from './store' import NProgress from 'nprogress' // Progress 进度条 import 'nprogress/nprogress.css'// Progress 进度条样式 import { Message } from 'element-ui' import { getToken } from '@/utils/auth' // 验权 const whiteList = ['/login'] // 不重定向白名单 router.beforeEach((to, from, next) => { NProgress.start() if (getToken()) { if (to.path === '/login') { next({ path: '/' }) } else { if (store.getters.name.length === 0) { store.dispatch('GetInfo').then(res => { // 拉取用户信息 router.addRoutes(store.getters.routers)//添加后台路由表 next({ ...to, replace: true }) }).catch(e => { store.dispatch('FedLogOut').then(() => { Message.error('验证失败,请重新登录'+e.message) next({ path: '/login' }) }) }) } else { next() } } } else { if (whiteList.indexOf(to.path) !== -1) { next() } else { next('/login') NProgress.done() } } }) router.afterEach(() => { NProgress.done() // 结束Progress })
4.绑定路由表

路径 @/layout/componets/SideBar/index.vue 刚开始发现addRouters()之后能访问但是并没有在菜单中显示,打印出来看了下router.option.router没有添加的路由,但是自己在store里面的却有,所以这里路由绑定我就换成了store里的routers,成功显示。

routes() { return this.$store.getters.routers//大坑。。 },

源码地址

GitHub源码地址

最新回复(0)