路由配置
路由加载规则
Teek 已经将路由分为了两类:一类是静态路由,一类是权限路由(动态路由)。
- 静态路由指的是 Teek 一定会加载的路由,如登录页面、404 页面等,是在路由对象初始化的时候 必然 一起初始化的路由
- 权限路由指的是满足了 指定权限 才加载的路由,具有权限校验功能,如 Teek 角色和 Visitor 角色看到路由可能不一样,Teek 在初始化的时候,就会根据角色去筛选出角色拥有的路由进行加载
- 静态路由最先加载,随着路由对象初始化和加载,而权限路由靠后,是在路由的前置钩子
beforeEach
里进行动态加载 - 静态路由一定是写在项目里,权限路由既可以是写在代码里,也可以是后端传来的动态路由
异步懒加载
当项目庞大的时候,推荐使用 异步懒加载 来加载路由,这样可以实现按需加载。
异步懒加载指的是在访问到该路由才加载该路由,而不是一次性加载完所有路由,因为一次性加载完会导致初次访问时,页面长时间白屏,因为 Teek 需要耗费大量时间去加载所有路由。
Vue 官方方式
官方推荐的方式是使用 import
来进行异步懒加载:
export const rolesRoutes: RouterConfigRaw[] = [
{
path: "/home",
name: "Home",
component: () => import("@/views/home/index.vue")
meta: {
title: "首页",
},
},
]
而 Teek 基于 Vue 官方方式再次衍生了另外两种方式:
Component 字符串方式
component
可以是一个字符串:
export const rolesRoutes: RouterConfigRaw[] = [
{
path: "/home",
name: "Home",
component: "/home/index",
meta: {
isAffix: true,
title: "首页",
icon: "HomeFilled",
},
},
];
当配置字符串方式后,Teek 会去寻找 src/view/home/index.vue
来渲染,寻找规则是在 component
字符串前自动加上 src/views
,在后面加上 .vue
。
Path 方式
如果不想写 component,Teek 还支持 Path 方式,直接用 path
代替 component
:
export const rolesRoutes: RouterConfigRaw[] = [
{
path: "/home/index",
name: "Home",
meta: {
title: "首页",
},
},
];
寻找规则与 Component 字符串方式一样,Teek 会自动在字符串前后加上 src/views
和 .vue
。
路由配置
下面演示一些基本的路由配置,实际上 Teek 还是建议去拉取项目运行,然后尝试在代码里配置几个路由就明白了如何使用。
标题 & 图标
使用 title
来当菜单、面包屑、标签页渲染的标题,使用 icon
当渲染的图标。
import { HomeFilled } from "@element-plus/icons-vue";
export const rolesRoutes: RouterConfigRaw[] = [
{
path: "/home",
name: "Home",
component: import("@/views/home/index.vue"),
meta: {
title: "首页",
icon: HomeFilled,
},
},
];
如果您给 Teek 全局注册了 ElementPlus 图标或其他图标,则 icon
可以直接写字符串名字:
export const rolesRoutes: RouterConfigRaw[] = [
{
path: "/home",
name: "Home",
component: import("@/views/home/index.vue"),
meta: {
title: "首页",
icon: "HomeFilled",
},
},
];
icon
支持 ElementPlus 内置的图标,也支持 Iconify 的图标,具体请看 图标。
标签页固定
标签页是记录打开过的历史路由,具有可删除功能,但是有时候我们需要将某个路由如首页直接固定到标签页的第一个位置,不允许删除,则使用 isAffix
属性:
export const rolesRoutes: RouterConfigRaw[] = [
{
path: "/home",
name: "Home",
component: import("@/views/home/index.vue"),
meta: {
title: "首页",
isAffix: true,
},
},
];
路由缓存
使用 isKeepAlive
属性即可对路由进行缓存。
生效前提:Vue 组件的 name
必须与对应路由的 name
保持一致:
<template></template>
<script setup lang="ts">
defineOptions({ name: "Home" });
</script>
路由 name
和 isKeepAlive
属性如下:
export const rolesRoutes: RouterConfigRaw[] = [
{
path: "/home",
name: "Home",
component: import("@/views/home/index.vue"),
meta: {
title: "首页",
isKeepAlive: true,
},
},
];
菜单隐藏
上文有说过,一个路由对应一个菜单,当我们不希望路由当作菜单渲染,则使用 hideInMenu
属性:
export const rolesRoutes: RouterConfigRaw[] = [
{
path: "/home",
name: "Home",
component: import("@/views/home/index.vue"),
meta: {
title: "首页",
hideInMenu: true,
},
},
];
菜单渲染(一个)
如果一个父路由 A 只有一个子路由 B,菜单栏默认不会渲染父路由 A,而是将子路由 B 作为父级菜单。
如果希望父路由 A 渲染为父级菜单,子路由 B 为子级菜单,则使用 alwaysShowRoot
属性:
export const rolesRoutes: RouterConfigRaw[] = [
{
path: "/components",
name: "Components",
meta: {
title: "组件",
},
children: [
{
path: "message",
name: "MessageDemo",
component: () => import("@/views/components/message/index.vue"),
meta: {
title: "消息组件",
alwaysShowRoot: true,
},
},
],
},
];
提示
当父路由有多个子路由的时候,则该属性失效,此时父路由一定是父菜单,子路由是子菜单。
菜单渲染(多个)
假设一个父级路由(菜单)下有五个子级路由(菜单),但是有 4 个子级路由 hideInMenu: true
,此时页面看到了一个父级菜单和一个子级菜单。
这明显不合理,因为按照 菜单渲染(一个) 里提到的 alwaysShowRoot
特性,应该将子级路由代替父级路由显示在菜单栏,为了让 alwaysShowRoot
特性生效,Teek 提供了另一个配置 moreRouteChildrenHideInMenuThenOnlyOne
:
const layoutSettings: Partial<Settings> = {
/**
* 这是路由和菜单呼应可能产生的问题而需要配置:alwaysShowRoot 为 false 情况(确保您了解路由的配置规则,如果不了解,前往 router/router-config 查看)
* true:存在多个二级路由,但是只有一个二级路由 hideInMenu 为 false,举例:有 5 个二级路由,但是有 4 个二级路由 hideInMenu: true,则需要开启 true,确保菜单只渲染剩下的路由
*
* 为 true 的场景较少见,如果真的遇到,则开启为 true,否则不建议开启,虽然无脑 true 能无需后顾之忧,但是会多重复一次过滤递归,即消耗点性能
*
*/
moreRouteChildrenHideInMenuThenOnlyOne: false,
};
开启这个配置后,Teek 会扫描两轮路由表来初始化菜单,会多消耗一轮扫描的性能,所以没遇到这个场景的时候,不推荐设为 true。
更多的路由配置请参考 Teek 的路由文件。