深入理解 Vue Router

在前端单页应用(SPA)中,路由是连接用户操作与页面展示的核心桥梁。Vue Router 作为 Vue 官方的路由管理器,提供了丰富的功能和灵活的配置。本文将围绕"路由模式"、"router 与 route 的区别"、"导航守卫的种类"以及"完整的导航解析流程"四个方面,带你深入理解 Vue Router 的工作机制。

一、路由模式:hash 与 history 的实现原理

Vue Router 支持两种主流的路由模式:hash 模式 和 history 模式。它们的底层实现机制不同,决定了使用方式和部署时的差异。

1. hash 模式

hash 模式是基于 URL 中 # 后面的内容变化实现的。浏览器不会将 # 后的部分发送到服务器,因此不会触发页面刷新。

  • 监听机制:通过监听 window.onhashchange 事件,捕获 hash 值的变化。
  • 优点:
    • 兼容性好,支持 IE 及以下版本。
    • 部署简单,刷新页面不会 404。
  • 缺点:
    • URL 不够美观,带有 # 符号。

2. history 模式

history 模式依赖 HTML5 提供的 pushStatereplaceState API,可以在不刷新页面的情况下修改 URL。

  • 监听机制:通过监听 popstate 事件,捕获浏览器前进/后退操作。
  • 优点:
    • URL 更干净,没有 #
  • 缺点:
    • 需要后端配合,刷新页面或直接访问子路径时,需将所有请求重定向到入口文件(如 index.html),否则会返回 404。
    • 对低版本浏览器支持不佳。

二、router 与 route 的区别

在 Vue 组件中,我们常常使用 this.$routerthis.$route,但它们代表的含义完全不同:

router

  • 是 Vue Router 的实例对象,包含整个路由的配置和控制方法。
  • 常用方法:
    • this.$router.push():跳转到指定路由,添加一条历史记录。
    • this.$router.replace():替换当前路由,不添加历史记录。
    • this.$router.go(n):前进或后退 n 步。

route

  • 是当前激活路由的信息对象,包含与当前路径相关的所有信息。
  • 常用属性:
    • this.$route.path:当前路径,如 /user/123
    • this.$route.params:动态路由参数,如 { id: 123 }
    • this.$route.query:查询参数,如 ?tab=profile 对应 { tab: 'profile' }
    • this.$route.name:当前路由的名称。
    • this.$route.meta:路由元信息,常用于权限控制。

简言之:router 是"路由器",负责操作;route 是"当前路线",负责提供信息。

三、导航守卫的种类

Vue Router 提供了多种导航守卫,用于在路由跳转前后执行逻辑控制,分为三大类:

1. 全局守卫

作用于整个应用,定义在 router 实例上:

  • router.beforeEach(to, from, next):全局前置守卫,常用于登录验证。
  • router.beforeResolve(to, from, next):全局解析守卫,2.5+ 引入,所有组件内守卫和异步路由组件解析完成后触发。
  • router.afterEach(to, from):全局后置钩子,不能拦截导航,常用于页面埋点。

2. 路由独享守卫

定义在单个路由配置中,仅对该路由生效:

  • beforeEnter(to, from, next):进入该路由前触发,用法与全局守卫类似。

3. 组件内守卫

定义在 Vue 组件内部,与组件生命周期紧密结合:

  • beforeRouteEnter(to, from, next):组件被激活前调用,此时组件实例尚未创建,无法访问 this
  • beforeRouteUpdate(to, from, next):当前路由改变但组件被复用时调用(如 /user/1/user/2)。
  • beforeRouteLeave(to, from, next):离开当前路由时调用,可用于提示用户保存未提交的表单。

四、完整的导航解析流程

Vue Router 的导航过程是一个链式调用的过程,每一步都可以中断或继续。以下是完整的流程:

  1. 导航触发:用户点击 <router-link> 或调用 $router.push()
  2. 调用失活组件的 beforeRouteLeave:如从 /user/1 跳转到 /about
  3. 调用全局 beforeEach 守卫。
  4. 调用重用组件的 beforeRouteUpdate(若组件被复用)。
  5. 调用路由独享的 beforeEnter
  6. 解析异步组件(若该路由配置了异步组件)。
  7. 调用激活组件的 beforeRouteEnter
  8. 调用全局 beforeResolve 守卫。
  9. 导航被确认。
  10. 调用全局 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 执行 beforeRouteEnternext 的回调,此时组件实例已创建,可通过回调参数访问。
相关推荐
zabr3 分钟前
AI时代,为什么我放弃Vue全家桶,选择了Next.js + Supabase
前端·aigc·ai编程
egghead2631614 分钟前
React常用hooks
前端·react.js
whysqwhw14 分钟前
Http与Https
面试
科粒KL17 分钟前
前端学习笔记-浏览器渲染管线/一帧生命周期/框架更新
前端·面试
whysqwhw22 分钟前
GET 与 POST
面试
凉_橙22 分钟前
什么是抽象语法树?
前端·javascript
成小白23 分钟前
前端实现分片上传
前端
页面魔术26 分钟前
尤雨溪: 我们没有放弃虚拟 dom
前端·javascript·vue.js
欧阳码农28 分钟前
langgraph开发Deep Research智能体-项目搭建
前端·后端·langchain
再吃一根胡萝卜29 分钟前
TCP三次握手机制的深入解析
前端