Skip to content

路由配置

在pro中提供了一套完整的路由系统,可以根据动态路由文件自动生成所需要的菜单结构。

静态路由

静态路由也可以称之为基础路由,是一个完全脱离菜单的路由,可以用于一些不需要菜单的页面,比如登录页、404页面等。

router/static-routes.ts中来配置我们的静态路由。

路由菜单

菜单的生成完全依赖于路由文件router/dynamic-routes.ts,会自动基于这个文件下的路系统动态的去生成所需要的菜单结构。

所有与菜单相关的参数全部罗列到meta属性下并为菜单扩展了如下的一些参数:

ts
interface RouteMeta {
  title?: string // 菜单标题
  icon?: string // 菜单图标
  hideInMenu?: boolean // 在菜单中隐藏
  parentKeys?: string[] // 隐藏菜单配置选中的父级菜单
  url?: string // iframe模式,会自动使用这个url
  hideInBreadcrumb?: boolean // 在面包屑中隐藏
  hideChildrenInMenu?: boolean // 在菜单中隐藏子节点
  keepAlive?: boolean // 是否进行保活配置
  target?: '_blank' | '_self' | '_parent' // 链接打开方式,当配置的path为全连接的时候
  affix?: boolean // 开启多页签模式的情况下,是否作为固定的页签展示
  access?: (string | number)[] // 权限管理,如果当前用户没有这个权限,那么将不会显示这个菜单
}
interface RouteMeta {
  title?: string // 菜单标题
  icon?: string // 菜单图标
  hideInMenu?: boolean // 在菜单中隐藏
  parentKeys?: string[] // 隐藏菜单配置选中的父级菜单
  url?: string // iframe模式,会自动使用这个url
  hideInBreadcrumb?: boolean // 在面包屑中隐藏
  hideChildrenInMenu?: boolean // 在菜单中隐藏子节点
  keepAlive?: boolean // 是否进行保活配置
  target?: '_blank' | '_self' | '_parent' // 链接打开方式,当配置的path为全连接的时候
  affix?: boolean // 开启多页签模式的情况下,是否作为固定的页签展示
  access?: (string | number)[] // 权限管理,如果当前用户没有这个权限,那么将不会显示这个菜单
}

小贴士

默认情况下,我们使用的是后端api接口加载菜单的形式,如果你想要通过前端进行加载的话,那么你需要在.env环境中配置一下VITE_APP_LOAD_ROUTE_WAY的加载方式

默认是BACKEND表示后端加载菜单和路由,改用FRONTEND后会通过src/router/dynamic-routes.ts去加载菜单和路由的信息。

此功能支持是在release@0.0.13以及以后支持的。

后端菜单

在大多数情况下,我们的菜单都是由后端来提供的,所以我们需要将后端的菜单数据转换成我们需要的路由结构。

后端菜单的数据结构如下:

ts
interface MenuDataItem {
  // 唯一id
  id?: string | number
  // 标题
  title: string | (() => VNodeChild)
  // 图标
  icon?: string | (() => VNodeChild)
  // 地址
  path: string
  // 绑定的哪个组件,默认自带的组件类型分别是:Iframe、RouteView和ComponentError
  component?: string
  // 子集菜单
  children?: MenuDataItem[]
  // 重定向地址
  redirect?: string
  // 哪些是固定页签
  affix?: boolean
  // 父级菜单的id
  parentId?: string | number | null
  // 同路由中的name,主要是用于保活的左右
  name?: string
  // 是否隐藏当前菜单
  hideInMenu?: boolean
  // 如果使用了隐藏,那么点击当前菜单的时候,可以使用父级的key
  parentKeys?: string[]
  // 如果当前是iframe的模式,需要有一个跳转的url支撑,其不能和path重复,path还是为路由
  url?: string
  // 是否存在面包屑
  hideInBreadcrumb?: boolean
  // 是否需要显示所有的子菜单
  hideChildrenInMenu?: boolean
  // 是否保活
  keepAlive?: boolean
  // 这里包含所有的父级元素
  matched?: MenuDataItem[]
  // 全连接跳转模式
  target?: '_blank' | '_self' | '_parent'
}
interface MenuDataItem {
  // 唯一id
  id?: string | number
  // 标题
  title: string | (() => VNodeChild)
  // 图标
  icon?: string | (() => VNodeChild)
  // 地址
  path: string
  // 绑定的哪个组件,默认自带的组件类型分别是:Iframe、RouteView和ComponentError
  component?: string
  // 子集菜单
  children?: MenuDataItem[]
  // 重定向地址
  redirect?: string
  // 哪些是固定页签
  affix?: boolean
  // 父级菜单的id
  parentId?: string | number | null
  // 同路由中的name,主要是用于保活的左右
  name?: string
  // 是否隐藏当前菜单
  hideInMenu?: boolean
  // 如果使用了隐藏,那么点击当前菜单的时候,可以使用父级的key
  parentKeys?: string[]
  // 如果当前是iframe的模式,需要有一个跳转的url支撑,其不能和path重复,path还是为路由
  url?: string
  // 是否存在面包屑
  hideInBreadcrumb?: boolean
  // 是否需要显示所有的子菜单
  hideChildrenInMenu?: boolean
  // 是否保活
  keepAlive?: boolean
  // 这里包含所有的父级元素
  matched?: MenuDataItem[]
  // 全连接跳转模式
  target?: '_blank' | '_self' | '_parent'
}

生成路由中的component的方法是通过,读取pages文件夹下的所有vue文件来实现的:

ts
const routerModules = import.meta.glob([
  '~/pages/**/*.vue',
  '!~/pages/**/*copy.vue',
  '!~/pages/**/component',
  '!~/pages/**/components',
  '!~/pages/**/composables',
  '!~/pages/**/hooks',
  '!~/pages/**/modules',
  '!~/pages/**/plugins',
  '!~/pages/**/tests',
  '!~/pages/**/test',
  '!~/pages/**/locales',
  '!~/pages/common',
  '!~/pages/exception',
])
const routerModules = import.meta.glob([
  '~/pages/**/*.vue',
  '!~/pages/**/*copy.vue',
  '!~/pages/**/component',
  '!~/pages/**/components',
  '!~/pages/**/composables',
  '!~/pages/**/hooks',
  '!~/pages/**/modules',
  '!~/pages/**/plugins',
  '!~/pages/**/tests',
  '!~/pages/**/test',
  '!~/pages/**/locales',
  '!~/pages/common',
  '!~/pages/exception',
])

带有!的表示排除的文件,这些文件都是一些公共的文件,不需要作为路由来生成,如果你还有其他的文件夹需要排除,可以在router/router-modules.ts中进行配置。

配置规则

在后台添加一个页面的的时候,可以以pages作为根目录,比如pages/system/user/index.vue,那么在后台添加的时候,只需要给component属性一个system/user即可。

如果当前页面是一个父级页面的话,那么可以在后台添加的时候,component需要填写一个RouteView,父级页面需要有一个children属性,用于存放子页面,并且需要配置一个redirect作为重定向的地址。

如果当前是一个iframe页面的话,我们需要配置一个url属性,这个属性是一个全连接的地址,其中component需要配置为IFrame,比如https://www.baidu.com

如果当前的页面是一个外链的话,我们不需要填写component的值或者你可以填写一个RouteView,然后在path属性中配置一个全连接的地址,比如https://www.baidu.com

保活功能更新

^0.0.19版本开始,保活功能不依赖路由的name名称。

v0.0.19以前版本配置

如果您想开启保活的功能,请确保正确配置了路由的name名称,这个名称是用于保活的唯一标识,如果您的路由没有配置name,那么保活功能将不会生效。

例如:页面test.vue

vue
<script lang="ts" setup>
defineOptions({
  name: 'CommonTest',
})
</script>

<template>
  <div>
    <h1>测试页面</h1>
  </div>
</template>
<script lang="ts" setup>
defineOptions({
  name: 'CommonTest',
})
</script>

<template>
  <div>
    <h1>测试页面</h1>
  </div>
</template>

那么对应的路由配置信息如下:

ts
{
  path: '/test',
  name: 'CommonTest',
  component: () => import('~/pages/test.vue'),
  meta: {
    title: '测试页面',
    icon: 'icon-test',
    keepAlive: true,
  },
},
{
  path: '/test',
  name: 'CommonTest',
  component: () => import('~/pages/test.vue'),
  meta: {
    title: '测试页面',
    icon: 'icon-test',
    keepAlive: true,
  },
},

这样就能实现页面保活的功能了。

Made by Antdv Pro Team with ❤️ Aibayanyu