深入理解 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 的回调,此时组件实例已创建,可通过回调参数访问。
相关推荐
LFly_ice20 分钟前
学习React-16-useContext
前端·学习·react.js
陈陈CHENCHEN27 分钟前
使用 Vite 快速创建 React 项目 - SuperMap iClient JavaScript / Leaflet
前端·react.js
用户68833620597030 分钟前
Progressive Web App (PWA)
前端
沢田纲吉31 分钟前
《LLVM IR 学习手记(二):变量表达式编译器的实现与深入解析》
前端·编程语言·llvm
小徐_233331 分钟前
VitePress 博客变身 APP,支持离线访问,只需这一招。
前端·vitepress·pwa
猪哥帅过吴彦祖32 分钟前
第 5 篇:WebGL 从 2D 到 3D - 坐标系、透视与相机
前端·javascript·webgl
折七33 分钟前
expo sdk53+ 集成极光推送消息推送 ios swift
前端·javascript·ios
猪哥帅过吴彦祖34 分钟前
Flutter 系列教程:布局基础 (上) - `Container`, `Row`, `Column`, `Flex`
前端·flutter·ios
lifejump34 分钟前
DVWA | XSS 跨站脚本注入
前端·xss
gplitems12335 分钟前
Tripfery - Travel & Tour Booking WordPress Theme Tested
前端