返回

Vue.js 路由精粹:深入剖析 Route 路由记录

前端

作为一个技术博客写作专家,我的使命是通过提供独到的见解,让看似复杂的概念变得触手可及。今天,我们踏上了一段奇妙的旅程,深入探索 Vue.js 路由系统的核心——Route 路由记录。

Route 路由记录,如其名,负责存储与特定路由相关的所有信息,包括组件、路径、名称等。通过分析其源代码,我们将揭开 Vue.js 路由引擎的神秘面纱,了解其运作机制以及如何利用它来构建动态且用户友好的 Web 应用程序。

构造器的魔力

整个 Route.js 文件只有唯一的一个构造器。让我们仔细审视一下它最后的两行代码:

if (path == '*') {
  this.path = _star
}

在这里,我们看到当路径为星号(*)时,它会将其替换为内部常量 _star。这表明使用星号作为路径将匹配任何未定义的路由。

前置知识

在深入研究 Route 路由记录源码之前,我们必须掌握两个关键概念:

  1. 响应式属性: Route 实例中的所有属性都是响应式的,这意味着当它们发生变化时,Vue.js 将自动更新依赖于它们的组件。
  2. 路由解析器: 它将传入的 URL 转换为匹配的路由记录。

代码剖析

import { _toString } from '../util/lang'
import Observer from '../observer/observer'

export class Route {
  constructor (router, path, matcher, config) {
    this.router = router
    this.path = path
    // store query as a string, still need to deal with it in other places
    this.query = config && config.query || {}
    this.hash = config && config.hash || ''
    this.params = config && config.params || {}
    this.name = config && config.name || null
    this.meta = config && config.meta || {}
    this.redirectedFrom = null
    this.fullPath = _toString(path, this.query, this.hash)

    // 把currentRoute保存为响应式变量
    router._currentRoute = this
    Observer.setTarget(this)
    // 把params和query都转换成响应式对象
    this.params = observerState(this.params)
    this.query = observerState(this.query)

    // 注册watch
    // 这里为每一项注册了一个watch,只要修改就会刷新视图
    this.router._initQueue.forEach((init) => { init(this) })

    // meta.beforeResolve和meta.afterResolve的注册
    this.matched = matcher.match(this.fullPath, this.params)

    // 全路径匹配和参数验证之后,执行meta.beforeResolve钩子
    callHook(this.matched, 'beforeResolve', (this.router._beforeEachHooks))

    // init 路由器
    // 确保meta.beforeResolve被调用后,当前的Route路由记录才被初始化,使组件获取路由信息
    this.init()
  }

让我们逐行分析这个构造器:

  1. 实例化 Route: 构造器接受 Vue Router 实例、路径、匹配器和配置对象作为参数。它初始化了 Route 实例的所有属性。
  2. 响应式属性: 重要的属性(如 params 和 query)被转换成响应式对象,以便 Vue.js 能够自动响应它们的更改。
  3. 观察路由状态: 将 currentRoute 保存为响应式变量,并为每一项属性注册一个侦听器,以在它们更改时刷新视图。
  4. 路由匹配: 使用匹配器将给定路径解析为匹配的路由记录,并将结果存储在 matched 数组中。
  5. beforeResolve 钩子: 在进行全路径匹配和参数验证之后,调用 meta.beforeResolve 钩子。
  6. 初始化路由器: 确保在调用 meta.beforeResolve 钩子后才初始化路由器,这样组件可以获取路由信息。

结语

通过分析 Route 路由记录源代码,我们获得了对 Vue.js 路由系统内部运作的深入理解。我们探讨了响应式属性、路由解析和构造器的作用,了解了它们如何协同工作以创建动态且健壮的路由体验。

希望这篇文章为各位的 Vue.js 之旅提供了有价值的见解。继续探索,在 Web 应用程序开发的道路上取得辉煌成就。