作者:管理员  历史版本:1  最后编辑:龚清  更新时间:2024-11-20 15:41

1、路由数据

完整版的ibps 路由设置文件在 src/router/routes.js

2、动态路由

2.1 addRoutes

在之前通过后端动态返回前端路由一直很难做的,因为vue-router必须是要vue在实例化之前就挂载上去的,不太方便动态改变。不过好在vue2.2.0以后新增了router.addRoutes
具体代码src/router/routes.js

2.2 具体实现

  1. 创建vue实例的时候将vue-router挂载,但这个时候vue-router挂载一些登录或者不用权限的公用的页面。
  2. 当用户登录后,获取用role,将role和路由表每个页面的需要的权限作比较,生成最终用户可访问的路由表。
  3. 调用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?

如果想在子系统也能访问到相同的地址,请在子系统添加相同的路由地址