Vue-Router4源码分析(一): createRouter

99 阅读1分钟

Vue-Router使用

<template> 
    <div>
        <router-link to="/">Go to Home</router-link> 
        <router-link to="/about">Go to About</router-link>
    </div>
    <router-view></router-view> 
</template>

创建路由器实例

import { createMemoryHistory, createRouter } from 'vue-router'
import HomeView from './HomeView.vue' 
import AboutView from './AboutView.vue' 
const routes = [
    { path: '/', component: HomeView },
    { path: '/about', component: AboutView }
] 
const router = createRouter({
    history: createWebHistory(),
    routes
})

本地调试,在 node_modules/vue-router/dist/vue-router.mjs 中打 debugger

Vue-Router初始化

createWebHistory()返回类型定义如下:

export interface RouterHistory {
    readonly base: string 
    readonly location: HistoryLocation 
    readonly state: HistoryState push(to: HistoryLocation, data?: HistoryState): void 
    replace(to: HistoryLocation, data?: HistoryState): void 
    go(delta: number, triggerListeners?: boolean): void 
    listen(callback: NavigationCallback): () => void 
    createHref(location: HistoryLocation): string destroy(): void 
}

createWebHistory()实现:

export function createWebHistory(base?: string): RouterHistory {
  base = normalizeBase(base)

  const historyNavigation = useHistoryStateNavigation(base)
  const historyListeners = useHistoryListeners(
    base,
    historyNavigation.state,
    historyNavigation.location,
    historyNavigation.replace
  )
  function go(delta: number, triggerListeners = true) {
    if (!triggerListeners) historyListeners.pauseListeners()
    history.go(delta)
  }

  const routerHistory: RouterHistory = assign(
    {
      // it's overridden right after
      location: '',
      base,
      go,
      createHref: createHref.bind(null, base),
    },

    historyNavigation,
    historyListeners
  )

  Object.defineProperty(routerHistory, 'location', {
    enumerable: true,
    get: () => historyNavigation.location.value,
  })

  Object.defineProperty(routerHistory, 'state', {
    enumerable: true,
    get: () => historyNavigation.state.value,
  })

  return routerHistory
}

createWebHistory() 内执行 useHistoryStateNavigation() 和 useHistoryListeners() 两个方法,返回的融合后的一个集合对象。

createRouter()返回全局路由对象,包含了路由实例和常用的内置方法。类型定义如下:

export interface Router { 
    // 当前路由 
    readonly currentRoute: Ref<RouteLocationNormalizedLoaded> 
    // 路由配置项 
    readonly options: RouterOptions 
    // 是否监听 
    listening: boolean
    // 添加路由 
    addRoute(parentName: RouteRecordName, route: RouteRecordRaw): () => void addRoute(route: RouteRecordRaw): () => void 
    // 删除路由 
    removeRoute(name: RouteRecordName): void 
    // 是否存在路由
    name=xxx hasRoute(name: RouteRecordName): boolean 
    // 获取所有路由
    matcher getRoutes(): RouteRecord[] clearRoutes(): void 
    // 返回路由地址的标准化版本
    resolve( to: RouteLocationRaw, currentLocation?: RouteLocationNormalizedLoaded ): RouteLocation & { href: string }
    // 路由push跳转
    push(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined> 
    // 路由replace跳转
    replace(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined> 
    // 路由回退
    back(): ReturnType<Router['go']> 
    // 路由前进 
    forward(): ReturnType<Router['go']>
    // 路由跳页 
    go(delta: number): void 
    // 全局导航守卫 
    beforeEach(guard: NavigationGuardWithThis<undefined>): () => void 
    beforeResolve(guard: NavigationGuardWithThis<undefined>): () => void 
    afterEach(guard: NavigationHookAfter): () => void
    // 路由错误处理 
    onError(handler: _ErrorHandler): () => void 
    // 路由器是否完成初始化导航
    isReady(): Promise<void> 
    // 路由安装方法
    install(app: App): void 
}