后端返回路由格式:
[
{
"path": "/node",
"component": "Layout",
"children": [
{
"path": "index",
"component": "/node/index",
"meta": {
"icon": "host",
"title": "主机管理"
},
"name": "node"
}
]
},
{
"path": "/cluster",
"component": "Layout",
"children": [
{
"path": "index",
"component": "/cluster/index",
"meta": {
"icon": "cluster",
"title": "集群管理"
},
"name": "cluster"
}
]
},
{
"path": "/storage",
"component": "Layout",
"children": [
{
"path": "index",
"component": "/storage/index",
"meta": {
"icon": "storage",
"title": "存储管理"
},
"name": "storage"
}
]
},
{
"redirect": "/vm",
"path": "/vmManage",
"component": "Layout",
"children": [
{
"path": "/vm",
"component": "/vm/index",
"meta": {
"icon": "vm",
"title": "虚拟机列表"
},
"name": "vm"
}
]
},
{
"redirect": "/hostResource",
"path": "/resource",
"component": "Layout",
"children": [
{
"path": "/hostResource",
"component": "/resource_monitor/host_resource/index",
"meta": {
"icon": "host",
"title": "主机资源"
},
"name": "hostResource"
},
{
"path": "/vmResource",
"component": "/resource_monitor/VM_resource/index",
"meta": {
"icon": "vm",
"title": "虚拟机资源"
},
"name": "vmResource"
}
],
"meta": {
"icon": "resource",
"title": "资源监控"
},
"name": "resource"
},
{
"redirect": "/404",
"path": "*",
"hidden": true
}
]
处理后端返回的路由表中的 component ,将 "Layout" 转换为组件对象,children中component为页面组件的路径
将默认路由和动态路由合并constantRoutes.concat(routes),最后router.addRoutes()
前置导航守卫
import router from './router'
import store from './store'
import NProgress from 'nprogress'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login']
router.beforeEach(async(to, from, next) => {
// 关闭l所有layer弹窗
Layer.prototype.$layer.closeAll()
NProgress.start()
document.title = getPageTitle(to.meta.title)
// 去往登录界面的路由跳转-->路由放行
if (to.path === '/login' && !sessionStorage.getItem('roles')) {
store.state.permission.routes = []
next()
} else {
// 判断用户是否已经登录
await loginpermit().then(async(res) => {
if (res && sessionStorage.getItem('roles')) {
try {
// 判断是否进行路由过滤
if (store.state.permission.routes.length <= 0) {
const role = [sessionStorage.getItem('roles')]
// 获取动态路由信息
const accessRoutes = await store.dispatch('permission/generateRoutes', role)
console.log(accessRoutes)
// 添加路由权限
router.addRoutes(accessRoutes)
// 赋值渲染路由
router.options.routes = store.state.permission.routes
const rolePage = {
'sysadmin': { path: '/node/index' },
'secadmin': { path: '/terminal/index' },
'auditadmin': { path: '/eventAudit/index' },
'user': { path: '/vmManage' },
'monitoradmin': { path: '/monitor/index' }
}
// 保证权限添加完成并重新进行跳转
next({ ...rolePage[role], replace: true })
// next({ path: to.path, replace: true })
} else {
// 已经进行路由过滤-->放行
next()
NProgress.done()
}
} catch (error) {
// 捕获异常-->主要是获取用户信息的异常,此处是必要的,返回数据异常极容易造成路由过滤问题,
console.log('add permission error', error)
}
} else {
logout()
// 不存在登录令牌,校验路由白名单-->此处是必要的,首次加载路由必须通过该方式进行渲染
if (whiteList.indexOf(to.path) !== -1) {
next()
NProgress.done()
} else {
// 路由指向的位置不在白名单范围内,且用户并没有登录令牌,直接跳转登录界面-->跳转白名单内容即可,会重新执行beforeEach,通过白名单逻辑进行渲染
await store.dispatch('user/resetToken')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
}).catch(async() => {
await store.dispatch('user/resetToken')
next(`/login?redirect=${to.path}`)
NProgress.done()
})
}
})
router.afterEach(() => {
NProgress.done()
})
在获取动态路由信息时,对路由表进行处理
// 字符串路径转为组件对象
// 将后端传回的"componentUrl": "Layout", 转为"component": Layout组件对象
export const loadViewsd = (view) => {
// 使用异步组件 实现路由懒加载 提升首屏加载速度
// 这个特殊的 `require` 语法将会告诉 webpack
// 自动将你的构建代码切割成多个包
return function(resolve) {
require(['@/views/cloud_desk' + view + '.vue'], resolve)
}
// CommonJS模块 运行时加载 获取到对象 编译时无法做静态优化
// 首屏加载速度慢
// return require('@/views/cloud_desk' + view + '.vue').default
// return require('@/views' + view + '.vue').default
}
// 格式化route,处理component
export function formatRouter(routes) {
routes.forEach((route) => {
if (route.component) {
// Layout组件特殊处理
if (route.component === 'Layout') {
route.component = Layout
} else {
route.component = loadViewsd(route.component)
}
}
if (route.children && route.children.length) {
route.children = formatRouter(route.children)
}
})
return routes
}