以下是在实习时,交给我的一项任务,让我理清路由的相关问题,以下是一些学习记录
(框架中路由模块已经都定义好了,以下只是我在学习过程中理解的思路)
npm install vue-router@4
Vue 3 的引入方式如下(其中 RouteRecordRaw 是路由项目的 TS 类型)。
(在src/router目录下的index.ts中的一些配置)
import { createRouter, createWebHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
//定义路由数组
const routes: Array = [
// ...
]
const router = createRouter({
// import.meta.env. 这个变量,
//它是由 Vite 提供的环境变量
history: createWebHistory(import.meta.env.BASE_URL),
routes,
})
export default router
export interface RouteMeta {
// 路由title 一般必填
title: string;
// 动态路由可打开Tab页数
dynamicLevel?: number;
// 动态路由的实际Path, 即去除路由的动态部分;
realPath?: string;
// 是否忽略权限,只在权限模式为Role的时候有效
ignoreAuth?: boolean;
// 可以访问的角色,只在权限模式为Role的时候有效
roles?: RoleEnum[];
// 是否忽略KeepAlive缓存
ignoreKeepAlive?: boolean;
// 是否固定标签
affix?: boolean;
// 图标,也是菜单图标
icon?: string;
// 内嵌iframe的地址
frameSrc?: string;
// 指定该路由切换的动画名
transitionName?: string;
// 隐藏该路由在面包屑上面的显示
hideBreadcrumb?: boolean;
// 如果该路由会携带参数,且需要在tab页上面显示。则需要设置为true
carryParam?: boolean;
// 隐藏所有子菜单
hideChildrenInMenu?: boolean;
// 当前激活的菜单。用于配置详情页时左侧激活的菜单路径
currentActiveMenu?: string;
// 当前路由不再标签页显示
hideTab?: boolean;
// 当前路由不再菜单显示
hideMenu?: boolean;
// 菜单排序,只对第一级有效
orderNo?: number;
// 忽略路由。用于在ROUTE_MAPPING以及BACK权限模式下,生成对应的菜单而忽略路由。2.5.3以上版本有效
ignoreRoute?: boolean;
// 是否在子级菜单的完整path中忽略本级path。2.5.3以上版本有效
hidePathForChildren?: boolean;
}
其中 index.ts 是路由的入口文件,如果路由很少,那么可以只维护在这个文件里
如果项目稍微复杂一些,可以拆分成多个文件: index.ts 和 routes.ts 等等,在 routes.ts 里维护路由树的结构,在 index.ts 导入路由树结构并激活路由,同时可以在该文件里配置路由钩子。
如果项目更加复杂,再把 routes 拆分得更细,例如 定义一些业务模块,再统一导入到 index.ts 文件里。
项目路由配置存放于 src/router/routes 下面。 src/router/routes/modules用于存放路由模块,在该目录下的文件会自动注册。
在 src/router/routes/modules 内的 .ts 文件会被视为一个路由模块。
一个路由模块包含以下结构
import type { AppRouteModule } from '/@/router/types';
import { LAYOUT } from '/@/router/constant';
import { t } from '/@/hooks/web/useI18n';
const dashboard: AppRouteModule = {
path: '/dashboard',
name: 'Dashboard',
component: LAYOUT,
redirect: '/dashboard/analysis',
meta: {
icon: 'ion:grid-outline',
title: t('routes.dashboard.dashboard'),
},
children: [
{
path: 'analysis',
name: 'Analysis',
component: () => import('/@/views/dashboard/analysis/index.vue'),//按需引入,懒加载方式
meta: {
affix: true,
title: t('routes.dashboard.analysis'),
},
},
{
path: 'workbench',
name: 'Workbench',
component: () => import('/@/views/dashboard/workbench/index.vue'),
meta: {
title: t('routes.dashboard.workbench'),
},
},
],
};
export default dashboard;
那路由模块和对应的组件(views文件夹中)实现了页面跳转具体的逻辑是怎么样的呢。
首先我们不是初始化完成了嘛,
在main.ts中也完成了以下定义
创建app实例
挂载在app
导出
通过在app上挂载了路由并导出,我们就可以全局使用路由了,我们定义的那些路由模块也就可以使用实现功能了
1 点击组件(按钮、router-lnk),
读取调用path所指向的地址( src/router/routes/modules )
,然后修改了浏览器地址栏中的url
2 相应的路由监听到地址栏url的变化3 路由内部会遍历所有Route组件,使用路由规则进行匹配4 当路由规则匹配成功,就由router-view展示出相关组件的内容
(所有路由组件,要在访问后进行渲染,都必须在父级组件里带有 router-view 标签,router-view 在哪里,路由组件的代码就渲染在哪个节点上,一级路由的父级组件,就是 src/App.vue 这个根组件)
其中最基础的配置就是 里面直接就是写一个 router-view ,整个页面就是路由组件。
当我们登录成功直接跳转到首页 dashboard/analysis
首页路由指的是应用程序中的默认路由,当不输入其他任何路由时,会自动重定向到该路由下,并且该路由在Tab上是固定的,即使设置affix: false也不允许关闭
首页路由配置的是/dashboard/analysis,那么当直接访问 http://localhost:3100/ 会自动跳转到http://localhost:3100/#/dashboard/analysis 上(用户已登录的情况下)
可以将pageEnum.ts中的BASE_HOME更改为需要你想设置的首页即可
export enum PageEnum {
// basic home path
// 更改此处即可
BASE_HOME = '/dashboard',
}
在 src/router/routes/modules 内新增一个模块文件。
比如新增 test.ts 文件
import type { AppRouteModule } from '/@/router/types';
import { LAYOUT } from '/@/router/constant';
import { t } from '/@/hooks/web/useI18n';
const dashboard: AppRouteModule = {
path: '/about',
name: 'About',
component: LAYOUT,
redirect: '/about/index',
meta: {
icon: 'simple-icons:about-dot-me',
title: t('routes.dashboard.about'),
},
children: [
{
path: 'index',
name: 'AboutPage',
component: () => import('/@/views/sys/about/index.vue'),
meta: {
title: t('routes.dashboard.about'),
icon: 'simple-icons:about-dot-me',
},
},
],
};
export default dashboard;
此时路由已添加完成,不需要手动引入,放在src/router/routes/modules 内的文件会自动被加载。