1、路由数据
完整版的ibps 路由设置文件在 src/router/routes.js
。
2、动态路由
2.1 addRoutes
在之前通过后端动态返回前端路由一直很难做的,因为vue-router必须是要vue在实例化之前就挂载上去的,不太方便动态改变。不过好在vue2.2.0以后新增了router.addRoutes
具体代码src/router/routes.js
。
2.2 具体实现
- 创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。
- 当用户登录后,获取用role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。
- 调用router.addRoutes(store.getters.addRouters)添加用户可访问的路由。
使用vuex管理路由表,根据vuex中可访问的路由渲染顶部和侧边栏组件。
2.3 router.js
首先我们实现router.js
路由表(src/router/utils.js
)下面只是截取部分关键代码
import layoutHeaderAside from '@/layout/header-aside'
import menuUtil from '@/utils/menu'
// 由于懒加载页面太多的话会造成webpack热更新太慢,所以开发环境不使用懒加载,只有生产环境使用懒加载
const _import = require('@/utils/util.import.' + process.env.NODE_ENV)
const meta = { auth: true }
/**
* 动态布局
*/
function getLayout() {
return layoutHeaderAside
}
/**
* 错误页面
*/
const errorPage = {
path: '*',
redirect: '/404',
hidden: true
}
const errorUrl = '/system/error/404'
const idKey = menuUtil.ID_KEY
const labelKey = menuUtil.LABEL_KEY
const nameKey = menuUtil.NAME_KEY
const iconKey = menuUtil.ICON_KEY
const parentIdKey = menuUtil.PARENT_KEY
const childrenKey = menuUtil.CHILD_KEY
const urlKey = menuUtil.URL_KEY
const layoutKey = 'layout'
const defaultRouterAlias = '/router-alias/'
// 异步挂载的路由
// 动态需要根据权限加载的路由表 该路由表通过后台获取
export function generateRoutes(menus) {
const asyncRouterMap = []
for (const menu of menus) {
asyncRouterMap.push(generateTopRoute(menu))
}
asyncRouterMap.push(errorPage)
return asyncRouterMap
}
/**
* 构建第一级路由
* @param {*} menu
*/
function generateTopRoute(menu) {
const router = {
id: menu[idKey],
parentId: menu[parentIdKey],
path: '/' + menu[nameKey],
alias: defaultRouterAlias + menu[nameKey],
name: menu[nameKey],
component: getLayout(menu[layoutKey]),
meta: {
title: menu[labelKey],
icon: menu[iconKey] || 'file-o',
name: menu[nameKey],
defaultUrl: menu[urlKey],
...meta
}
}
if (menu[childrenKey] && menu[childrenKey].length > 0) {
router.children = generateSubRoutes(menu[childrenKey])
} else { // 添加顶部默认节点
router.children = [{
id: menu[idKey],
parentId: menu[parentIdKey],
path: 'index',
name: menu[nameKey],
alias: defaultRouterAlias + menu[nameKey],
component: getComputedUrl(menu[urlKey]),
meta: {
title: menu[labelKey],
icon: menu[iconKey] || 'file-o',
name: menu[nameKey],
defaultUrl: menu[urlKey],
...meta
}
}]
}
return router
}
/**
* 构建子路由
* @param {*} menus
*/
function generateSubRoutes(menus) {
const pool = []
const push = function(menus, namePrefix = []) {
menus.forEach(menu => {
const router = {
id: menu[idKey],
parentId: menu[parentIdKey],
path: [...namePrefix, menu[nameKey]].join('/'),
name: [...namePrefix, menu[nameKey]].join('-'),
alias: defaultRouterAlias + menu[nameKey],
component: getComputedUrl(menu[urlKey]),
meta: {
title: menu[labelKey],
icon: menu[iconKey] || 'file-o',
name: menu[nameKey],
defaultUrl: menu[urlKey],
...meta
}
}
if (menu[childrenKey] && menu[childrenKey].length > 0) {
push(menu[childrenKey], [...namePrefix, menu[nameKey]])
} else {
pool.push({
...router
})
}
})
}
push(menus)
return pool
}
/**
* 获取 组件url
* @param {*} menu
*/
function getComputedUrl(url) {
if (!url) return _import(errorUrl)
try {
if (isHttp(url)) {
return _import('/system/iframe/index')
} else if (url.indexOf('/d/') > -1) { // 数据模版
return _import('/platform/data/dataTemplate/template-list')
} else {
return _import(convertUrl(url)) || _import(errorUrl)
}
} catch (error) {
// console.warn(error)
return _import(errorUrl)
}
}
这里我们根据 vue-router官方推荐 的方法通过meta标签来标示改页面能访问的权限有哪些。如meta: { icon: menu[iconKey] || 'file-o'}
表示展示的图标。
注意事项:这里有一个需要非常注意的地方就是 404 页面一定要最后加载,如果放在constantRouterMap一同声明了404,后面的所以页面都会被拦截到404,详细的问题见addRoutes when you’ve got a wildcard route for 404s does not work
FAQ
1. 怎么新增个路由菜单不显示菜单里面,在代码里面进行访问
①、菜单管理-》添加
②、代码里面使用:
this.$router.push("路由地址")
// 或者别名路由
const alias = '别名'
this.$router.push('/router-alias/' + alias)
//更多路由传参
https://router.vuejs.org/zh/guide/essentials/navigation.html
2、菜单管理中配置的URL与前端显示的路由地址不一样
问题描述:
在菜单管理中,员工管理配置的URL地址是:/platform/org/employee/list,但前端显示的路由地址是/yhgl/userManage,两边不一致
问题解答:
1、采用的vue-route的嵌套路由+动态路由
路由地址:/yhgl/userManage 是在代码src\router\utils.js 中构建的动态路由,采用父子嵌套
/yhgl/userManage -----------> 对应是 yhgl(用户管理别名)/userManage(员工管理)
可以参考:https://router.vuejs.org/zh/guide/essentials/named-views.html#%E5%B5%8C%E5%A5%97%E5%91%BD%E5%90%8D%E8%A7%86%E5%9B%BE
2、动态构建路由,组件页面
你可以把每个页面当成一个vue组件
对应的实际页面:views/platform/org/employee/list ,前面的views写死代码里面
3. 不同的子系统相同的地址访问后怎么404?
如果想在子系统也能访问到相同的地址,请在子系统添加相同的路由地址