🦴 整段代码一句话定位
**这就是「脊椎总干」**把所有骨骼(路由)拼接在一起 → 装上关节(守卫) → 交给身体(Vue)使用
🧬 逐行人体结构讲解(超级通俗)
1. 导入零件(拿来骨骼、工具、图纸)
ts
import type { App } from 'vue'
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import { RedirectRoute } from '@/router/base'
import { createRouterGuards } from './router-guards'
...
import modules from '@/router/modules'
- 对应人体:拿来骨骼、关节、神经、肌肉
- 作用:把路由需要的所有工具、基础页面、模块路由全部导入
2. 定义「脊椎主干」RootRoute
ts
const RootRoute: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Root',
redirect: PageEnum.BASE_HOME,
component: Layout, // 骨架布局
children: [
...HttpErrorPage,
modules.projectRoutes,
modules.chartRoutes,
modules.previewRoutes,
modules.editRoutes
]
}
]
✨ 重点解释(必懂)
- path: '/' :人体的丹田 / 中心点
- component: Layout :套用整体骨架(躯干)
- children: [...] :把所有小骨骼(项目 / 图表 / 预览 / 编辑) 全部装到脊椎上→ 形成完整身体结构
3. 拼装「全身固定骨骼」
ts
export const constantRouter: any[] = [
LoginRoute, // 登录骨
...RootRoute, // 脊椎主干
RedirectRoute, // 重定向骨
ReloadRoute // 刷新骨
];
- 对应人体:把四肢、头、躯干全部拼好
- 作用:生成最终完整路由表
4. 创建「真正的脊椎」router 实例
ts
const router = createRouter({
history: createWebHashHistory(''), // 路由模式:哈希模式
routes: constantRouter, // 把骨骼装进去
strict: true,
})
- 对应人体:脊椎正式成型!
createWebHashHistory:网页路由模式(带 #)
5. 把脊椎安装到身体(Vue)
ts
export function setupRouter(app: App) {
app.use(router); // 装脊椎
createRouterGuards(router)// 装神经系统(路由守卫)
}
- 对应人体:
- 把脊椎(router)装到身体(Vue)
- 装上神经守卫,控制能不能走、去哪里
6. 导出脊椎,供全身使用
ts
export default router
🎯 这段代码最核心的 3 个功能(背会就够)
- 拼装所有路由(登录、主页、图表、预览、编辑、404)
- 统一使用 Layout 布局骨架
- 创建路由实例 + 挂载守卫
- 暴露给 main.ts 安装到 Vue
✅ 你必须记住的 5 个路由语法
createRouter→ 创建路由实例createWebHashHistory→ 哈希路由模式routes: []→ 路由表(骨骼清单)children: []→ 子路由(小骨骼)app.use(router)→ 安装路由到 Vue
Layout 是全局布局骨架组件,统一控制页面的整体结构;children 用于配置子路由,将各个业务模块的路由挂载到主路由下,形成路由嵌套结构。
🔥 路由核心总结(你现在已经掌握的)
我用最精简的话帮你收个尾,上午的学习完美收官:
- router/index.ts = 脊椎主干负责把所有路由拼在一起、创建实例、挂载守卫。
- Layout = 身体骨架所有页面都套在这个布局里。
- children = 脊椎上的小骨头项目、图表、预览、编辑路由都挂在这里。
- setupRouter = 把脊椎装到身体给 Vue 安装路由 + 神经系统(守卫)。
🧠 一句话定位
路由守卫 = 人体的「神经系统 + 大门保安」
你去哪里、能不能去、有没有资格去、走错路了怎么办,全靠它管!
🦿 逐段超通俗讲解(对应人体)
1. 导入工具
ts
import { Router } from 'vue-router';
import { PageEnum } from '@/enums/pageEnum'
import { loginCheck } from '@/utils'
拿来地图、门牌号、检查是否登录的工具。
2. 创建守卫(安装神经系统)
ts
export function createRouterGuards(router: Router) {
把神经保安安装到脊椎(router)上。
🔥 核心:router.beforeEach ------ 出发前检查(最重要)
ts
router.beforeEach(async (to, from, next) => {
意思:每次页面跳转之前,先经过我这一关!
里面做了 4 件大事:
① 记录外部带来的参数(比如链接里的 t=xxx)
ts
Object.assign(window.route.params, to.query)
把别人发给你的链接参数存起来,方便后面用。
② 开启加载动画
ts
Loading.start();
页面跳转时转圈圈。
③ 走错路 → 自动去 404
ts
if (isErrorPage === -1) {
next({ name: 404 })
}
你想去一个不存在的页面 → 保安直接把你送到 404。
④ 最重要:没登录 → 强制去登录页
ts
if (!loginCheck()) {
next({ name: 登录页 })
}
没登录 = 没带身份证保安不让进任何页面,直接赶去登录!
⑤ 全部通过 → 放行
ts
next()
可以去你想去的页面了。
🔥 router.afterEach ------ 到达之后收尾
ts
router.afterEach((to) => {
document.title = 标题
Loading.finish()
})
- 页面到了 → 关掉加载动画
- 改网页标题
🔥 router.onError ------ 出错了抓 bug
ts
router.onError((error) => {
console.log(error, '路由错误')
})
神经报错了 → 控制台打印出来。
🎯 最精简总结(背会就够)
路由守卫 = 全程保安 + 神经系统
- 没登录 → 强制去登录
- 页面不存在 → 去 404
- 跳转前开启 loading
- 跳转后关闭 loading + 改标题
- 出错了捕获错误
这个文件 = 项目骨架上的一节独立骨头(图表业务路由) 专门管:/chart 工作空间 这个页面的跳转规则。
逐行超通俗讲解(超简单)
1. 导入需要的工具
ts
import { RouteRecordRaw } from 'vue-router'
import { ChartEnum } from '@/enums/pageEnum'
拿来路由类型 + 页面地址常量(门牌号)
2. 定义 "页面组件的加载方式"
ts
const importPath = {
'ChartEnum.CHART_HOME_NAME': () => import('@/views/chart/index.vue')
}
- 作用:懒加载
- 人话:用到这个页面时,才去加载组件,让项目更快
- 对应人体:这块骨头要用的时候才长出来,不浪费资源
3. 定义一节完整的 "骨头 = 路由"
ts
const chartRoutes: RouteRecordRaw = {
path: ChartEnum.CHART_HOME, // 地址:/chart
name: ChartEnum.CHART_HOME_NAME, // 名字:工作空间
component: 加载页面组件, // 页面对应的.vue文件
meta: {
title: '工作空间', // 网页标题
isRoot: true, // 是根页面
noKeepAlive: true, // 不缓存
}
}
每个字段的意思(必懂)
- path:页面地址 URL(骨头的位置)
- name:路由名称(骨头的名字)
- component:对应的页面组件(骨头长啥样)
- meta:路由附加信息(骨头的属性:标题、是否缓存)
4. 导出骨头,给脊椎使用
ts
export default chartRoutes
把这节图表骨头 导出,最终会被装到 router/index.ts 的 children 里,拼成完整脊椎!
🎯 超级精简总结
modules/xxx.route.ts = 一节业务骨头
- 定义一个页面的 地址、名字、组件、属性
- 采用 路由懒加载 优化速度
- 最终被汇总到主路由,成为骨架的一部分
✅ 你现在彻底懂了!
我用三句话收个尾:
- router/index.ts = 脊椎主干
- router-guards.ts = 神经保安
- modules/xxx.route.ts = 一节业务子骨头
1. isRoot: true ------ 标记 "这是一级根页面"
人话解释:
这个页面是 "顶级主页",不是其他页面的子页面。
作用(你项目里真实用途):
- 让侧边栏、导航栏 知道:这是顶级菜单
- 让标签页 知道:这是根页面,不是弹出层 / 子页面
- 让权限、路由守卫知道:这是一个独立的主页面
比喻(骨架):
isRoot = 这是一节主脊椎骨,不是小碎骨。
2. noKeepAlive: true ------ 不缓存页面
人话解释:
每次离开这个页面 → 销毁页面 每次回来 → 重新加载、重新请求数据
作用(超级关键!)
为什么要关闭缓存?
因为你的项目是 大屏可视化编辑器!
- 图表数据是动态的
- 配置是实时变化的
- 如果缓存了,你修改图表后,返回再进来还是旧的
关闭缓存 = 每次进入都是最新状态!
比喻(骨架):
noKeepAlive = 每次离开,骨头就拆掉; 每次回来,重新装一根新骨头。 保证永远是最新的!
🎯 最精简总结(背会就够)
✔ isRoot: true
标记这是一级主页面,给导航、菜单、权限识别用。
✔ noKeepAlive: true
不缓存页面 ,每次进入都重新加载,适合图表编辑器、数据实时变化的页面!
你现在彻底懂路由了!
我给你收个尾:
- router/index.ts → 脊椎主干
- router-guards.ts → 神经保安
- modules/xxx.route.ts → 一节业务骨头
- isRoot → 标记主骨
- noKeepAlive → 不缓存,永远最新
这个文件 = 骨骼收纳盒 / 关节连接器
把所有零散的业务骨头 ,全部收拢到一起 ,方便主路由 index.ts 一次性拿走!
逐行看懂(超级简单)
ts
import projectRoutes from './project.router'
import chartRoutes from './chart.route'
import previewRoutes from './preview.route'
import editRoutes from './edit.route'
👉 把 4 节业务骨头全部拿进来
- 项目骨
- 图表骨
- 预览骨
- 编辑骨
ts
export default {
projectRoutes,
chartRoutes,
previewRoutes,
editRoutes
}
👉 打包成一盒,统一导出 就像把四肢骨骼打包好,交给脊椎组装!
🎯 它到底有什么用?(超级关键)
如果没有这个文件:主路由 index.ts 要写 4 行 import
有了这个文件:主路由只需要 1 行 import 就能拿到全部路由!
ts
import modules from '@/router/modules'
作用:简化代码、统一管理
结合人体骨架比喻(终极好记)
modules/index.ts = 骨骼组装盒
- 项目骨
- 图表骨
- 预览骨
- 编辑骨
全部打包 → 交给 脊椎(index.ts) 拼装成完整骨架!
✅ 恭喜你!
整个路由系统 → 100% 全部学完!
我给你做终极总复盘:
- router/index.ts → 脊椎主干(拼装所有路由)
- router-guards.ts → 神经保安(权限、跳转、加载)
- modules/index.ts → 骨骼收纳盒(收拢所有业务路由)
- modules/xxx.route.ts → 一节节业务骨头
- children → 嵌套小骨头
- 懒加载 → 优化速度
- redirect → 自动跳转
- isRoot → 标记主页面
modules/index.ts 是路由模块统一导出文件,将项目、图表、预览、编辑等业务路由进行集中打包导出 ,主路由只需导入这一个文件即可获取所有子路由,简化代码结构、便于维护管理。
先一句话总结
这堆代码 = 项目所有页面的路径 + 名称 统一管理 作用:写路由、跳转页面、权限控制 全靠它!
逐段给你翻译(秒懂版)
1. 导入 ResultEnum
ts
import { ResultEnum } from '@/enums/httpEnum'
意思:**导入网络请求状态码(404、500、403)**后面用来匹配错误页面。
2. 图表相关页面(核心业务)
ChartEnum ------ 图表创建 / 编辑页
ts
export enum ChartEnum {
CHART_HOME = '/chart/home/:id(.*)*', // 图表设计页地址
CHART_HOME_NAME = 'ChartHome', // 页面名字
}
用途:你做图表拖拽设计的页面
PreviewEnum ------ 预览页
ts
export enum PreviewEnum {
CHART_PREVIEW = '/chart/preview/:id(.*)*', // 预览地址
CHART_PREVIEW_NAME = 'ChartPreview', // 名字
}
用途:做完图表,看效果的页面
EditEnum ------ JSON 编辑页
ts
export enum EditEnum {
CHART_EDIT = '/chart/edit/:id(.*)*', // 编辑JSON
CHART_EDIT_NAME = 'ChartEdit', // 名字
}
用途:直接改代码的页面
3. PageEnum ------ 整个项目所有页面(最重要!)
这就是你问的 "页面总目录"
ts
export enum PageEnum {
// 登录
BASE_LOGIN = '/login',
BASE_LOGIN_NAME = 'Login',
// 首页(项目)
BASE_HOME = '/project',
BASE_HOME_NAME = 'Project',
// 我的项目
BASE_HOME_ITEMS = '/project/items',
BASE_HOME_ITEMS_NAME = 'Project-Items',
// 我的模板
BASE_HOME_TEMPLATE = '/project/my-template',
BASE_HOME_TEMPLATE_NAME = 'Project-My-Template',
// 模板市场
BASE_HOME_TEMPLATE_MARKET = '/project/template-market',
// 错误页面
ERROR_PAGE_NAME_403 = 'ErrorPage403',
ERROR_PAGE_NAME_404 = 'ErrorPage404',
ERROR_PAGE_NAME_500 = 'ErrorPage500'
}
通俗翻译:
/login→ 登录页/project→ 项目首页/project/items→ 我的项目列表/project/my-template→ 我的模板/project/template-market→ 模板市场- 403 / 404 / 500 → 错误页面
4. 错误页面映射(超级关键)
ts
export const ErrorPageNameMap = new Map([
[ResultEnum.NOT_FOUND, PageEnum.ERROR_PAGE_NAME_404],
[ResultEnum.SERVER_FORBIDDEN, PageEnum.ERROR_PAGE_NAME_403],
[ResultEnum.SERVER_ERROR, PageEnum.ERROR_PAGE_NAME_500]
])
意思:
网络报错 → 自动跳对应错误页面
- 404 找不到 → 跳 404 页面
- 403 无权限 → 跳 403 页面
- 500 服务器挂了 → 跳 500 页面
你最关心的:这些枚举在代码里怎么用?
我直接给你看真实用法!
1. 路由里用(你最开始看到的代码)
ts
component: Layout,
redirect: PageEnum.BASE_HOME, // 跳转到首页/project
2. 页面跳转用
ts
// 跳转到登录页
router.push(PageEnum.BASE_LOGIN)
// 跳转到预览页
router.push(PreviewEnum.CHART_PREVIEW)
3. 网络报错自动跳页
ts
if(code === 404) {
router.push(ErrorPageNameMap.get(404))
}
4. 判断当前页面
ts
if(route.name === PageEnum.BASE_HOME_NAME) {
console.log('我在首页')
}
终极大白话总结
你现在看的这个文件,就是:
整个项目的 "导航地图" + "地址簿"
所有页面:
- 登录
- 首页
- 项目
- 模板
- 图表设计
- 预览
- 编辑 JSON
- 各种错误页
路径和名字 全在这里统一管理!
一句话结论
CHART_HOME_NAME = 'ChartHome'这个字符串是给 Vue Router 用的 "页面身份证号",不是给用户看的标题!
它不显示在页面上 ,是路由内部识别页面用的。
它到底有哪 4 个用途?(全是实战用法)
1. 跳页面不用写路径,直接用名字!
这是最常用的!
有了名字:
ts
// 跳转到图表页
router.push({ name: 'ChartHome' })
不用写:
ts
router.push('/chart/home/123')
好处:路径改了,代码不用改!
2. 判断当前在哪个页面(超级常用)
ts
if (route.name === 'ChartHome') {
console.log('当前在图表设计页')
}
你看,不用判断 URL,直接判断名字!
3. 面包屑导航用它找页面标题
界面上看到的:首页 / 我的项目 / 图表设计最后一段图表设计 ,就是通过 name: ChartHome 找到的!
ts
const titleMap = {
ChartHome: '图表设计',
Project: '项目首页',
Login: '登录'
}
4. 权限控制:根据页面名字判断能不能进
ts
const permission = ['ChartHome', 'Project']
if(permission.includes(route.name)){
可以进入
}
最通俗的比喻(秒懂)
-
path: /chart/home = 家庭住址
-
name: ChartHome = 你的姓名(身份证名)
-
找你家:看住址
-
识别你是谁:看姓名
路由也是一样:
- path = 浏览器地址栏的路径
- name = 代码内部识别页面的唯一名字
为什么要单独用枚举存起来?
ts
CHART_HOME_NAME = 'ChartHome'
因为:
- 防止手写拼写错误
- 统一管理,改一次全项目生效
- 编辑器有智能提示
最终超级大白话总结
ChartHome 这个页面名字:
不是给用户看的,是给代码用的 "页面身份证"
用来:
- 跳转页面
- 判断页面
- 显示面包屑
- 做权限控制