vue-admin-template 实现动态路由
可完全参考 vue-element-admin:https://github.com/PanJiaChen/vue-element-admin 中的实现。
但是有几个非常需要注意的地方,我第一次参照着实现了以后,过了一段时间做另一个项目居然又花了不少时间,遂做个详细记录。
需要改动的地方:
1、src/router/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | export const asyncRoutes = [ { path: '/permission' , component: Layout, redirect: '/permission/page' , alwaysShow: true , // will always show the root menu name: 'Permission' , meta: { title: 'Permission' , icon: 'lock' , roles: [ 'admin' , 'editor' ] // you can set roles in root nav }, children: [ { path: 'page' , component: () => import ( '@/views/permission/page' ), name: 'PagePermission' , meta: { title: 'Page Permission' , roles: [ 'admin' ] // or you can only set roles in sub nav } } ] }, // 404 page must be placed at the end !!! { path: '*' , redirect: '/404' , hidden: true } ] |
2、src/permission.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | import router from './router' import store from './store' import { Message } from 'element-ui' import NProgress from 'nprogress' // progress bar import 'nprogress/nprogress.css' // progress bar style import { getToken } from '@/utils/auth' // get token from cookie import getPageTitle from '@/utils/get-page-title' NProgress.configure({ showSpinner: false }) // NProgress Configuration const whiteList = [ '/login' , '/auth-redirect' ] // no redirect whitelist router.beforeEach(async(to, from, next) => { // start progress bar NProgress.start() // set page title document.title = getPageTitle(to.meta.title) // determine whether the user has logged in const hasToken = getToken() if (hasToken) { if (to.path === '/login' ) { // if is logged in, redirect to the home page next({ path: '/' }) NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939 } else { // determine whether the user has obtained his permission roles through getInfo const hasRoles = store.getters.roles && store.getters.roles.length > 0 if (hasRoles) { next() } else { try { // get user info // note: roles must be a object array! such as: ['admin'] or ,['developer','editor'] const { roles } = await store.dispatch( 'user/getInfo' ) // generate accessible routes map based on roles const accessRoutes = await store.dispatch( 'permission/generateRoutes' , roles) // dynamically add accessible routes router.addRoutes(accessRoutes) // hack method to ensure that addRoutes is complete // set the replace: true, so the navigation will not leave a history record next({ ...to, replace: true }) } catch (error) { // remove token and go to login page to re-login await store.dispatch( 'user/resetToken' ) Message.error(error || 'Has Error' ) next(`/login?redirect=${to.path}`) NProgress.done() } } } } else { /* has no token*/ if (whiteList.indexOf(to.path) !== -1) { // in the free login whitelist, go directly next() } else { // other pages that do not have permission to access are redirected to the login page. next(`/login?redirect=${to.path}`) NProgress.done() } } }) router.afterEach(() => { // finish progress bar NProgress.done() }) |
3、src/store/modules/permission.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | import { asyncRoutes, constantRoutes } from '@/router' /** * Use meta.role to determine if the current user has permission * @param roles * @param route */ function hasPermission(roles, route) { if (route.meta && route.meta.roles) { return roles.some(role => route.meta.roles.includes(role)) } else { return true } } /** * Filter asynchronous routing tables by recursion * @param routes asyncRoutes * @param roles */ export function filterAsyncRoutes(routes, roles) { const res = [] routes.forEach(route => { const tmp = { ...route } if (hasPermission(roles, tmp)) { if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, roles) } res.push(tmp) } }) return res } const state = { routes: [], addRoutes: [] } const mutations = { SET_ROUTES: (state, routes) => { state.addRoutes = routes state.routes = constantRoutes.concat(routes) } } const actions = { generateRoutes({ commit }, roles) { return new Promise(resolve => { let accessedRoutes if (roles.includes( 'admin' )) { accessedRoutes = asyncRoutes || [] } else { accessedRoutes = filterAsyncRoutes(asyncRoutes, roles) } commit( 'SET_ROUTES' , accessedRoutes) resolve(accessedRoutes) }) } } export default { namespaced: true , state, mutations, actions } |
4、src/store/getters.js
5、src/layout/components/Sidebar/index.vue
需要把 routes 改为 permission_routes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <template> <div : class = "{'has-logo':showLogo}" > <logo v- if = "showLogo" :collapse= "isCollapse" /> <el-scrollbar wrap- class = "scrollbar-wrapper" > <el-menu : default -active= "activeMenu" :collapse= "isCollapse" :background-color= "variables.menuBg" :text-color= "variables.menuText" :unique-opened= "false" :active-text-color= "variables.menuActiveText" :collapse-transition= "false" mode= "vertical" > <sidebar-item v- for = "route in permission_routes" :key= "route.path" :item= "route" :base-path= "route.path" /> </el-menu> </el-scrollbar> </div> </template> <script> import { mapGetters } from 'vuex' import Logo from './Logo' import SidebarItem from './SidebarItem' import variables from '@/styles/variables.scss' export default { components: { SidebarItem, Logo }, computed: { ...mapGetters([ 'permission_routes' , 'sidebar' ]), activeMenu() { const route = this .$route const { meta, path } = route // if set path, the sidebar will highlight the path you set if (meta.activeMenu) { return meta.activeMenu } return path }, showLogo() { return this .$store.state.settings.sidebarLogo }, variables() { return variables }, isCollapse() { return ! this .sidebar.opened } } } </script> |
分类:
Vue
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)