深入理解 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 的回调,此时组件实例已创建,可通过回调参数访问。
相关推荐
m0_61134931几秒前
什么是副作用(Side Effects)
开发语言·前端·javascript
狗头大军之江苏分军1 分钟前
她在结婚那天离开了:我们该重新谈谈“结婚这件事”
前端·后端
消失的旧时光-19431 分钟前
从命令式跳转到声明式路由:前端、Android、Flutter 的一次统一演进
android·前端·flutter·状态模式
王中阳Go5 分钟前
🚀 RAG 系统检索不准?是时候引入「离线精排」思维了!
后端·面试
icestone_kai7 分钟前
ngix开启跨域
前端
咸虾米_8 分钟前
uniapp使用history路由模式打包上线到前端网页托管的注意事项
前端·uni-app·vue3·unicloud·前端网页托管
前端无涯9 分钟前
React Router(web) 全解析:知识点、工作注意点及面试重点
前端·react.js·前端框架
EQ_雪梨蛋花汤11 分钟前
【NDK / JNI】Sceneform-EQR 集成 Filament JNI 源码:关键点与逐步操作记录
前端
C_心欲无痕12 分钟前
vue3 - shallowReactive浅层响应式对象(只对顶层属性)
前端·javascript·vue.js
AY呀12 分钟前
新手必读:React组件从入门到精通,一篇文章搞定所有核心概念
前端·javascript·react.js