1.动态生成路由
import Vue from 'vue'
import Router from 'vue-router'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css'// progress bar style
import store from '@/store'
import api from '@/api'
Vue.use(Router)
const router = new Router({
routes: [
{
path: '/home',
name: 'home',
component: () => import('@/views/home/home.vue'),
children: [],
},
{
path: '/login',
name: 'login',
component: () => import('@/views/login/login.vue'),
},
{
path: '/error',
name: 'error',
component: () => import('@/views/error.vue'),
}
]
})
// const whiteList = ['/login', '/authredirect']// no redirect whitelist
// // 全局钩子
// router.beforeEach((to, from, next) => {
// let token = localStorage.getItem('token');
// let userName = localStorage.getItem('user')
// NProgress.start() // start progress bar
// console.info(token)
// // 如果有token
// // token = 'undefined'
// if (token !== 'undefined') { // determine if there has token
// // 登录后进入登录页
// if (to.path === '/login') {
// next({path: '/home'})
// NProgress.done() // if current page is dashboard will not trigger afterEach hook, so manually handle it
// } else {
// addDynamicMenuAndRoutes(userName, to, from)
// NProgress.done()
// }
// } else {
// /* has no token*/
// if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入
// next()
// } else {
// next('/login') // 否则全部重定向到登录页
// NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
// }
// }
// }
// )
//
// router.afterEach(() => {
// NProgress.done() // finish progress bar
// })
router.beforeEach((to, from, next) => {
// 登录界面登录成功之后,会把用户信息保存在会话
// 存在时间为会话生命周期,页面关闭即失效。
let token = localStorage.getItem('token');
let userName = localStorage.getItem('user')
// token = ""
if (to.path === '/login') {
// 如果是访问登录界面,如果用户会话信息存在,代表已登录过,跳转到主页
if (token) {
next({path: '/home'})
} else {
next()
}
} else {
if (!token) {
// 如果访问非登录界面,且户会话信息不存在,代表未登录,则跳转到登录界面
next({path: '/login'})
} else {
// 加载动态菜单和路由
addDynamicMenuAndRoutes(userName, to, from)
next()
}
}
})
/**
* 加载动态菜单和路由
*/
function addDynamicMenuAndRoutes(userName, to, from) {
// 处理IFrame嵌套页面
// handleIFrameUrl(to.path)
if (store.state.app.menuRouteLoaded) {
console.log('动态菜单和路由已经存在.')
return
}
api.user.findMenus({'username': userName}).then(res => {
// 添加动态路由
let dynamicRoutes = addDynamicRoutes(res.data)
// 处理静态组件绑定路由
handleStaticComponent(router, dynamicRoutes)
router.addRoutes(router.options.routes)
// console.info(JSON.stringify(router.options.routes))
// 保存加载状态
store.commit('menuRouteLoaded', true)
// 保存菜单树
store.commit('setNavTree', res.data)
}).then(res => {
api.user.findPermissions({'username': userName}).then(res => {
// 保存用户权限标识集合
console.info(JSON.stringify(res.data))
store.commit('setPerms', res.data)
})
})
}
/**
* 添加动态(菜单)路由
* @param {*} menuList 菜单列表
* @param {*} routes 递归创建的动态(菜单)路由
*/
function addDynamicRoutes(menuList = [], routes = []) {
var temp = []
for (var i = 0; i < menuList.length; i++) {
if (menuList[i].menuChild && menuList[i].menuChild.length >= 1) {
temp = temp.concat(menuList[i].menuChild)
} else if (menuList[i].path && /\S/.test(menuList[i].path)) {
menuList[i].path = menuList[i].path.replace(/^\//, '')
// 创建路由配置
var route = {
path: "/" + menuList[i].path,
component: null,
name: menuList[i].menuName,
meta: {
icon: menuList[i].icon,
index: menuList[i].menuId,
}
}
try {
// 根据菜单URL动态加载vue组件,这里要求vue组件须按照url路径存储
// 如url="sys/user",则组件路径应是"@/views/sys/User.vue",否则组件加载不到
let array = menuList[i].path.split('/')
let url = ''
for (let i = 0; i < array.length; i++) {
url += array[i].substring(0, 1).toUpperCase() + array[i].substring(1) + '/'
}
url = url.substring(0, url.length - 1)
// console.log(url)
route['component'] = resolve => require([`@/views/${url}.vue`], resolve)
} catch (e) {
}
routes.push(route)
}
}
if (temp.length >= 1) {
addDynamicRoutes(temp, routes)
} else {
console.log('动态路由加载...')
// console.log(routes)
console.log('动态路由加载完成.')
}
return routes
}
/**
* 处理路由到本地直接指定页面组件的情况
* 比如'代码生成'是要求直接绑定到'Generator'页面组件
*/
function handleStaticComponent(router, dynamicRoutes) {
// console.info(JSON.stringify(router.options))
router.options.routes[0].children = router.options.routes[0].children.concat(dynamicRoutes)
}
export default router
动态生成路由 并将菜单信息保存到stroe中去
后台数据为:
[{"menuId":1,"parentId":0,"menuName":"系统管理","path":"/system","component":"/system","perms":null,"icon":"el-icon-s-platform","type":"0","orderNum":2,"createTime":"2017-12-27T08:39:07.000+0000","modifyTime":"2019-01-05T03:13:14.000+0000","menuChild":[{"menuId":3,"parentId":1,"menuName":"用户管理","path":"/system/user","component":"/system/user","perms":"user:view","icon":"el-icon-user-solid","type":"0","orderNum":1,"createTime":"2017-12-27T08:47:13.000+0000","modifyTime":"2019-01-21T22:45:55.000+0000","menuChild":null},{"menuId":4,"parentId":1,"menuName":"角色管理","path":"/system/role","component":"/system/role","perms":"role:view","icon":"el-icon-user","type":"0","orderNum":2,"createTime":"2017-12-27T08:48:09.000+0000","modifyTime":"2018-04-25T01:01:12.000+0000","menuChild":null},{"menuId":6,"parentId":1,"menuName":"部门管理","path":"/system/dept","component":"/system/dept","perms":"dept:view","icon":"iconfont iconzuzhijiagou","type":"0","orderNum":4,"createTime":"2017-12-27T08:57:33.000+0000","modifyTime":"2018-04-25T01:01:40.000+0000","menuChild":null},{"menuId":5,"parentId":1,"menuName":"菜单管理","path":"/system/menus","component":"/system/menus","perms":"menu:view","icon":"el-icon-menu","type":"0","orderNum":3,"createTime":"2017-12-27T08:48:57.000+0000","modifyTime":"2018-04-25T01:01:30.000+0000","menuChild":null},{"menuId":64,"parentId":1,"menuName":"字典管理","path":"/system/dict","component":"/system/dict","perms":"dict:view","icon":"el-icon-tickets","type":"0","orderNum":5,"createTime":"2018-01-18T02:38:25.000+0000","modifyTime":"2018-04-25T01:01:50.000+0000","menuChild":null}]},{"menuId":2,"parentId":0,"menuName":"系统监控","path":"/monitor","component":"/monitor","perms":null,"icon":"el-icon-s-order","type":"0","orderNum":6,"createTime":"2017-12-27T08:45:51.000+0000","modifyTime":"2019-01-22T22:27:12.000+0000","menuChild":[{"menuId":127,"parentId":2,"menuName":"服务器信息","path":"/monitor/systemInfo","component":"/monitor/systemInfo","perms":null,"icon":null,"type":"0","orderNum":3,"createTime":"2019-01-20T23:53:43.000+0000","modifyTime":"2019-01-20T23:57:00.000+0000","menuChild":null},{"menuId":124,"parentId":2,"menuName":"JVM信息","path":"/monitor/jvminfo","component":"/monitor/jvminfo","perms":null,"icon":null,"type":"0","orderNum":1,"createTime":"2019-01-17T18:33:30.000+0000","modifyTime":"2019-01-17T18:46:51.000+0000","menuChild":null},{"menuId":8,"parentId":2,"menuName":"在线用户","path":"/monitor/online","component":"/monitor/online","perms":"user:online","icon":"","type":"0","orderNum":1,"createTime":"2017-12-27T08:59:33.000+0000","modifyTime":"2018-04-25T01:02:04.000+0000","menuChild":null},{"menuId":122,"parentId":2,"menuName":"系统信息","path":"/monitor/system","component":"/monitor/system","perms":null,"icon":null,"type":"0","orderNum":5,"createTime":"2019-01-17T18:31:48.000+0000","modifyTime":"2019-01-17T18:39:46.000+0000","menuChild":null},{"menuId":113,"parentId":2,"menuName":"Redis监控","path":"/monitor/redis","component":"/monitor/redis","perms":"redis:view","icon":null,"type":"0","orderNum":3,"createTime":"2018-06-28T06:29:42.000+0000","modifyTime":null,"menuChild":null},{"menuId":121,"parentId":2,"menuName":"请求追踪","path":"/monitor/httptrace","component":"/monitor/httptrace","perms":null,"icon":null,"type":"0","orderNum":4,"createTime":"2019-01-17T18:30:29.000+0000","modifyTime":null,"menuChild":null},{"menuId":123,"parentId":2,"menuName":"Tomcat信息","path":"/monitor/tomcatinfo","component":"/monitor/tomcatinfo","perms":null,"icon":null,"type":"0","orderNum":2,"createTime":"2019-01-17T18:32:53.000+0000","modifyTime":"2019-01-17T18:46:57.000+0000","menuChild":null}]},{"menuId":144,"parentId":0,"menuName":"坐席服务管理","path":"/service","component":"/service","perms":null,"icon":"el-icon-menu","type":"0","orderNum":4,"createTime":"2017-12-27T08:39:07.000+0000","modifyTime":"2019-01-05T03:13:14.000+0000","menuChild":null},{"menuId":145,"parentId":0,"menuName":"规则管理","path":"/rule","component":"/rule","perms":null,"icon":"el-icon-document","type":"0","orderNum":5,"createTime":"2017-12-27T08:39:07.000+0000","modifyTime":"2019-01-05T03:13:14.000+0000","menuChild":null},{"menuId":142,"parentId":0,"menuName":"主页","path":"/home","component":"/home","perms":null,"icon":"el-icon-s-home","type":"0","orderNum":1,"createTime":"2017-12-27T08:39:07.000+0000","modifyTime":"2019-01-05T03:13:14.000+0000","menuChild":null},{"menuId":143,"parentId":0,"menuName":"知识管理","path":"/knowology","component":"/knowology","perms":null,"icon":"el-icon-location","type":"0","orderNum":3,"createTime":"2017-12-27T08:39:07.000+0000","modifyTime":"2019-01-05T03:13:14.000+0000","menuChild":null}]
路由加载完成以后通过 菜单管理显示
{{menu.menuName}}
{{menu.menuName}}
遍历所有的路由并显示后 在需要显示的地方调用
import {mapState} from 'vuex'
import MenuTree from "@/components/MenuTree"
export default {
components: {
MenuTree
},
methods: {
collapseOpen() {
this.$store.commit('collapseOpen')
},
collapseClose() {
this.$store.commit('collapseClose')
}
},
computed: {
...mapState({
themeColor: state => state.app.themeColor,
oldThemeColor: state => state.app.oldThemeColor,
collapse: state => state.app.collapse,
navTree: state => state.menu.navTree
})
}
}
显示效果为: