今天在看Vue Router时,重新整理了三部分内容:一是简单正则表达式路由;二是通过路由实现组件间通信;三是动态路由及其常见问题。 这几个知识点看起来分散,但本质上都围绕一句话展开:路由不仅负责页面跳转,还承担了参数约束、状态传递等职责。
一、先理解什么是路由
这个在我前几篇文章中也说到过;
在单页应用中,所谓路由,可以理解为"路径和组件之间的映射关系"。
当地址栏变化时,页面并不会像传统多页网站那样整页刷新,而是由路由系统决定"当前应该显示哪个组件"。 所以学习路由,核心其实就是学习三件事:
-
路径怎么写
-
参数怎么传
-
页面怎么匹配和切换
二、动态路由参数:最基础也最常用
1. 什么是动态路由
动态路由就是在路径中预留变量位置,让不同的地址映射到同一个组件。
例如:
TypeScript
/article/:id
这里的**:id**就是动态参数。
当访问:
TypeScript
/article/1
/article/2
/article/100
它们都可以进入同一个页面组件,只是参数不同。
2. 动态参数的作用
这种写法非常适合下面这些场景:
-
文章详情页
-
用户详情页
-
商品详情页
-
按编号查找资源
也就是说,组件是同一个,但展示的数据依赖于路径参数。
3. 获取动态参数
在Vue Router中,可以通过当前路由对象读取参数,例如:
TypeScript
route.params.id
这说明:路径参数属于路由的一部分,会随着地址变化而变化。
三、正则表达式路由:让参数更"合法"
普通动态参数虽然灵活,但也有一个问题:它太宽松了 。 比如**/user/abc** 和**/user/123**都可能匹配成功,但有时我们只希望接收数字。
这时就可以使用正则表达式路由。
四、正则表达式路由的语法
1. 匹配纯数字
TypeScript
/user/:id(\d+)
含义是:
-
:id是参数名
-
**(\d+)**表示参数必须由一个或多个数字组成
所以:
-
/user/1 可以匹配
-
/user/25 可以匹配
-
/user/abc 不能匹配
这类写法非常适合:
-
用户 id
-
订单编号
-
数据库主键
-
文章编号
2. 匹配日期格式
正则不只可以限制数字,也可以限制结构化字符串,例如日期:
TypeScript
/article/:date(\d{4}-\d{1,2}-\d{1,2})
它可以匹配类似:
-
2026-5-1 -
2026-05-15
这种设计说明一个很重要的思路:路由不仅负责跳转,还能提前校验参数格式。
也就是说,有些错误数据根本不应该进入页面组件,而应该在路由层就被拦住。
五、路由守卫配合参数校验
仅靠正则,可以筛掉一部分不合法路径,但很多时候还不够。
例如:
-
123是数字,但不一定是有效 id
-
2026-15-99符合某种字符结构,但不是真实日期
这时就需要结合路由守卫进一步判断。
1. beforeEnter的作用
beforeEnter是某个路由独享的守卫,它会在进入该路由之前执行。
它适合做:
-
参数校验
-
权限校验
-
进入页面前的前置判断
2. 守卫的价值
它的核心作用不是"让代码更复杂",而是:把无效访问挡在组件外面。
这样做有几个好处:
-
页面组件更纯粹,只负责展示
-
非法参数更早被发现
-
路由逻辑和业务逻辑分层更清晰
六、通过路由实现组件间通信
除了页面跳转,路由还可以充当"共享信息的中间层"。
这在兄弟组件通信里尤其好理解。
1. 为什么能通信
如果两个组件都依赖同一个路由对象,那么:
-
一个组件修改路由参数
-
另一个组件监听路由参数变化
这样就形成了通信效果。
本质不是组件直接传值,而是:两个组件共同读取同一份路由状态。
2. 常见方式:使用query
例如地址可能从:
TypeScript
/search
变成:
TypeScript
/search?tag=vue
/search?tag=python
/search?tag=java
这时一个组件负责"改地址",另一个组件负责"读地址",通信就完成了。
3. 这种方式适合哪些场景
通过query做通信,比较适合:
-
搜索关键词切换
-
标签筛选
-
排序方式切换
-
列表页条件共享
因为这些内容本来就很适合体现在 URL 上。
4. 优点
这种方式有几个明显优势:
-
刷新页面后状态仍然存在
-
链接可以直接复制分享
-
前进后退时状态可追踪
-
逻辑比"层层传 props"更直观
5. 需要注意的问题
路由通信虽然方便,但也不是万能的。 它更适合"页面状态 "而不是"复杂业务数据"。
例如:
-
一个简单标签名,用query很合适
-
一个大型对象,放进路由就不合适
所以要记住:路由适合传轻量、可序列化、适合暴露在地址栏中的信息。
七、动态路由:运行时再添加路由
前面的路由规则大多是在一开始就写好的,这叫静态路由。 而动态路由则不同,它是在程序运行过程中,再通过代码把路由补进去。
1. 什么是动态添加路由
Vue Router提供了方法,可以在运行时添加新路由。
常见形式有两种:
-
添加一级路由
-
向某个父路由下添加子路由
这意味着:系统可以先启动,等拿到数据后,再决定哪些页面真正可访问。
2. 动态路由的典型使用场景
动态路由非常适合:
-
后台管理系统权限控制
-
根据后端返回菜单生成页面
-
按角色加载不同功能模块
-
插件式页面扩展
比如管理员能看到 A、B、C 页面,普通用户只能看到 A、B 页面,这种情况下动态路由就很实用。
3. 动态路由的核心思路
一般流程是:
-
用户进入系统
-
请求后端接口,获取可访问菜单或路由信息
-
根据返回结果组装路由
-
调用动态添加方法注册到路由系统
-
再跳转到目标页面
这个流程本质上是把"页面访问权限"从前端静态配置,变成"前后端协同决定"。
八、动态路由为什么常和import.meta.glob一起出现
当后端只返回一个组件路径或组件标识时,前端需要把它映射成真正可加载的组件。
这时常见思路是:预先收集一批可用组件,再根据后端返回的信息去匹配。
import.meta.glob的作用,就是批量获取某个目录下的组件模块映射关系。
如果去拼接字符串导入文件,控制台会报

它解决的问题是:
-
前端不能随意拼任意字符串去导入文件
-
需要先告诉构建工具"这些组件可能会被动态使用"
所以它在动态路由里很常见。
九、404 页面为什么在动态路由里更重要
静态路由项目里,404 页面只是"兜底"。 但在动态路由场景中,404 的意义更大,因为失败可能来自更多环节:
-
后端返回了错误的组件路径
-
前端没有找到对应组件
-
用户访问了不存在的地址
-
动态路由还没加载完成就跳转了
因此,404 页面不仅是"页面不存在"的提示,还是一种失败兜底机制。
可以理解为:只要动态匹配链路中任何一步出错,都应该有一个明确的兜底出口。
十、动态路由常见问题总结
这是学习中最容易混乱的部分,也是最值得复习的部分。
1. 路由已经添加了,但页面还是进不去
可能原因:
-
路由添加时机太晚
-
目标地址在添加完成前就已经开始跳转
-
添加后没有重新导航
本质问题是:目标路由匹配时,系统里还没有这条记录。
2. 添加成功了,却进入了 404
可能原因:
-
后端返回的组件标识不对
-
组件映射表中没有该组件
-
路径写法和实际注册结果不一致
-
404 路由注册过早,先把路径吃掉了
3. 一直重复跳转
这是动态路由里非常经典的问题。 通常出现在前置守卫里动态添加路由后,又立即重新进入同一个判断逻辑。
常见原因:
-
没有设置"是否已经加载过动态路由"的标记
-
重新跳转后又重复添加
-
next调用逻辑混乱
这说明在动态路由中,状态控制和跳转控制必须非常清晰。
4. 守卫里重复放行
在导航守卫中,放行逻辑必须明确。 如果一次导航流程里重复调用放行方法,容易出现异常行为,例如:
-
重复跳转
-
控制台警告
-
导航结果不符合预期
所以要养成一个习惯:每次守卫执行,最终只应该产生一个明确的导航结果。
5. 路由已经存在,却还在重复添加
动态路由不是"每次跳转都加一次",而应该是:
-
首次加载时添加
-
或在权限变化时重新生成
否则会造成逻辑冗余,甚至引发命名冲突、调试困难等问题。
十一、静态路由和动态路由怎么区分理解
可以用一句话概括:
-
静态路由:项目启动前就确定好的路由
-
动态路由:项目运行后根据条件再补充的路由
再进一步理解:
-
固定页面适合静态路由
-
权限页面适合动态路由
-
通用详情页适合动态参数
-
参数格式严格时适合正则约束
把这几种思路分开,就不容易混淆。
十二、重点
1. 正则路由的重点不是"会写正则",而是"限制参数合法性"
它能让无效地址在进入组件前就被筛掉。
2. 路由不仅能跳转,还能传递轻量状态
尤其适合搜索、筛选、标签切换这类场景。
3. 动态路由的核心不是addRoute这个方法本身
而是"根据外部条件决定页面访问权限"的整体思路。
4. 动态路由最容易出问题的地方在守卫
包括加载时机、重复跳转、重复放行、404 兜底等。
5. 学路由时要把"路径、参数、匹配、守卫、组件"看成一个整体
这样知识就不会碎片化。
总结
这次复盘也让我对Vue Router的理解更完整了一些。 以前更容易把路由当成"页面跳转工具",现在意识到了,它其实同时承担了:
-
页面切换
-
参数约束
-
状态传递
-
权限控制
-
异常兜底
如果只是做简单页面切换,路由看起来并不复杂;但一旦涉及正则匹配、兄弟组件通信和动态路由,就会发现它其实是前端工程化里非常关键的一层。
这样路由这一块就会从"会用"逐步走向"理解清楚"。