# 路由和菜单

项目中默认使用了前端预设的静态路由, 要使用后端返回的数据来生成动态路由和菜单的话需要将 @/config/index.js 中的 route.useBackendDataAsRoute 设为 true

本项目不支持二级以上的路由,虽然路由配置可以无限级,但是实际上是二级路由的效果。 因为在处理路由数据时会将二级以上的路由缩减为其叶子节点,也就是说如果有如下路由:

const routes = [
    {
        path: '/a',
        component:A,
        children: [
            {
                path: 'b',
                component:B,
                children: [
                    {
                        path: 'c',
                        component:C
                    },
                    {
                        path: 'd',
                        component:D,
                        children: [
                            {
                                path: 'e',
                                component:E,
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

缩减后是下面的形式:

const routes = [
    {
      path: '/a',
      component: A,
      children: [
        { path: 'b/c', component: C },
        { path: 'b/d/e', component: E }
      ]
    }
]

这样做的目的是为了避免多级路由缓存失效的问题,而且大部分情况下,三级路由(或更高)可以借助动态组件来实现同样的效果。

# 路由配置项

本项目的路由配置除了component以外,与vue-router没有区别,仅在meta中添加了一些用于生成路由和菜单的字段。

当使用前端定义路由时(@/configroute.useBackendDataAsRoutefalse),component可以是字符串, 也可以是一个返回Promise的函数,比如() => import('xxx'),否则只能为字符串。

component为字符串时,比如组件路径是@/view/test/indexPage.vue, 那么值可以是test/test/indextest/indexPagetest/indexPage.vue, 具体可以看@/router/util.js 中的 generateRoutes 方法。

这里约定,配置项中只有根节点的path以'/'开头(这也是vue-router所要求的),并且只有根节点和叶子节点可以自定义component

目前根节点的component固定为Layout

此外,所有根节点(经过降级缩减)的redirect属性都将设为其第一个子节点的fullPathredirect有值的不作处理。

路由配置会经过一些变换以转换成el-admin-layout需要的菜单,所以项目中的路由meta的数据结构为el-admin-layout中路由meta菜单meta的统合

因为一些需要,项目中的路由meta相比于上述会多一些,具体如下表:

# Route.meta Extra Attributes:

参数 说明 类型 默认
hidden 是否在菜单中隐藏 boolean -
noAuth true时路由不需要鉴权 boolean -

注意

路由meta上的noCachenoAuth会被子路由继承,优先使用子路由的值

# 路由免登陆

@/router/guardian/accessControl.js 中有这么一句:

const noLoginList = ['/login', '/register', '/403', '/404', '/500']

noLoginList匹配的路由不需要登录(同样也不需要鉴权),直接放行。

一般来说,不需要登录即可访问的路由都不以Layout作为组件,并且这东东基本不需要修改。

# 路由守卫

所有路由守卫全部位于@/router/guardian中。

预设的路由守卫如下:

  • nprogress进度条守卫
  • 登陆和权限守卫

注意

路由守卫是有先后顺序的,请查看@/router/guardian/index.js

# 首屏加载效果

想体验的可以把 network 设为 slow 3g 就可以在在线实例看到效果。

原理很简单,在 index.html 里有这么一段:

<div id="app">
    <div>
        <img>
        <p>资源加载中......</p>
    </div>
</div>

vuejs 初始化完成后,app 里的内容会被替换,从而实现加载效果。

# 骨架屏

通常情况下,路由组件都是以 () => import(...) 的形式异步引入, 如果想让路由在加载异步组件时显示,可以使用以下方式:

function lazyLoadView(component) {
    const AsyncHandler = () => ({component, loading: Skeleton})
    return () => Promise.resolve({
        functional: true,
        render(h, {data, children}) {
            return h(AsyncHandler, data, children)
        }
    })
}

//将路由配置中的component项改为以下形式
component: lazyLoadView(import(...))

这是vue-router的官方文档 ,项目中具体的使用方式可以查看 @/router/util #generateRoutes方法。

关于 AsyncHandler 的更多选项,可以查看vue官方文档

上次更新:: 3/8/2021, 7:48:53 PM