Jinuss's blog Jinuss's blog
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

前端可视化
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • React

  • Vue

  • JavaScript文章

  • 学习笔记

  • openlayers

  • threejs

  • MapboxGL

  • 工具

  • 源码合集

    • Pinia源码浅析
    • 《Vue3源码》笔记
    • vue-router源码浅析
      • pinia-plugin-persistedstate源码浅析
      • 《Openlayers源码》笔记
      • 《Leaflet源码》笔记
    • 前端
    • 源码合集
    东流
    2024-05-20
    目录

    vue-router源码浅析

    # vue router 源码浅析

    # 概述

    # 常用属性介绍

    # RouterLink

    RouterLink实际上就是通过 vue 的defineComponent方法定义的组件,创建一个<a>标签, 该组件内部会调用useLink()方法,这个useLink会根据参数 props 创建响应式的链接属性,以及处理链接事件

    # RouterView

    RouterView同上,也是 vue 的defineComponent定义的组件

    # 常用 API 介绍

    # createRouter

    createRouter 方法用来创建一个路由实例,该方法接受一个参数,该参数是一个对象,该对象用来配置路由实例,通常如下创建

    const router = createRouter({
      history: createWebHashHistory(),
      routes,
    });
    
    1
    2
    3
    4

    createRouter首先就会调用createRouterMatcher方法,返回的值标记为matcher

    # createRouterMatch

    createRouterMatch方法接受一个routes数组和全局配置,会返回addRoute、removeRoute、getRoutes、getRecordMatcher、resolve等方法。在其内部会遍历routes并调用addRoute

    addRoute: 添加路由 removeRoute: 移除路由 getRoutes: 获取路由 getRecordMatcher: 获取路由记录匹配器 resolve:解析路由

    createRouter方法创建的实例有以下属性

    return {
      currentRoute,
      listening: true,
      addRoute,
      removeRoute,
      hasRoute,
      getRoutes,
      resolve,
      options,
      push,
      replace,
      go: (step) => routerHistory.go(step),
      back: () => go(-1),
      forward: () => go(1),
      beforeEach: beforeGuards.add,
      beforeResolve: beforeResolveGuards.add,
      afterEach: afterGuards.add,
      onError: errorListeners.add,
      isReady,
      install,
    };
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    • go、back、forward方法本质上调用的都是 options.history.go 方法,而这个go方法本质上还是调用的window.history.go。

    • addRoute方法:可以用于动态添加路由,接受两个参数,parentRouteName 和 route;若 parentRouteName 为空,则添加到根路由下,否则添加到指定路由下。其内部是调用的matcher的addRoute方法。

    • removeRoute方法:接受一个参数name,用于删除指定路由。首先会调用matcher的getRecordMatcher方法,如果返回有值,则调用matcher的removeRoute方法。

    • hasRoute方法:接受一个参数name,判断路由是否存在,调用matcher的getRecordMatcher方法

    • getRoutes方法: 返回所有路由,遍历调用matcher的getRoutes方法的返回值,取其record

    # createWebHistory

    createWebHistory创建一个 history 模式路由, 返回一个 routerHistory 对象。该对象提供了以下方法:go、replace、push、listen、destory、pauselisten等方法以及location和state对象。

    createWebHistory方法中主要用到了useHistoryStatenavigation和useHistoryListeners方法.

    实现步骤: 1.接受一个参数base,调用normalizeBase方法进行路由规范化处理,去除协议和域名部分,确保路由以/开头和不以/结尾 2.调用useHistoryStatenavigation方法,创建一个navigation对象,用于记录路由变化和状态 3.调用useHistoryListeners方法,创建一个listeners对象,用于记录路由变化监听器 4.赋值 2、3 的返回给routerHistory,并返回

    # useHistoryStateNavigation

    useHistoryStateNavigation方法首先会根据window.location和 base 获取当前的路由值, 然后判断window.history.state,如果其不为空则调用changeLocation在其内部调用window.history.replaceState或者window.history.pushState,最后改变 state 的值。

    useHistoryStateNavigation方法返回的push和replace方法均会调用changeLocation方法,其中push会调用两次

    # useHistoryListeners

    useHistoryListeners方法接受四个参数base、调用useHistoryStateNavigation方法返回的state、location属性和replace方法 其内部实现主要逻辑是监听popstate和beforeunload事件,执行相应的路由切换逻辑,从而实现前端路由的控制和管理

    popstate事件:浏览器的历史记录发生变化(用户的执行某些导航操作,如点击浏览器的前进、后退按钮或者通过 javascript 调用history.pushState、history.replaceState、history.back()和history.forward()等方法时会触发,触发popstate事件,vue router内部会执行popStateHandler函数,popStateHandler函数主要是判断state,如果state存在,则更新当前位置、历史状态并计算位置偏移值;如果state不存在,则调用replace方法更新。最后遍历了注册的所有监听器listeners并执行监听器, 传参为三个:currentLocation.value:当前位置信息、from:之前的位置信息、路由变化的对象:delta、type:'pop'、direction:正负表示前进、后退还是未知方向

    beforeunload事件:用于在用户即将离开当前页面(关闭页面、刷新页面、导航到其他页面)时触发,触发该事件时,vue router会执行beforeUnloadListener函数,调用history.replaceState方法

    以上两个监听的事件会在destory函数中移除

    # createWebHashHistory

    createWebHashHistory 会创建一个 hash 模式的路由,同createWebHistory一样,接受一个参数base,会自动给 base 加上#,再调用createWebHistory并返回

    # createMemoryHistory

    createMemoryHistory 会基于内存创建一个 history,主要用于处理服务端渲染 SSR,即不依赖于浏览器的实际 url 地址变化,而是在内存中维护路由历史记录。

    createMemoryHistory 返回的是一个routerHistory对象,这个对象包含replace、push、listen、destroy、go方法。createMemoryHistory内部维护了两个数组listeners、quue,listeners用于记录listen方法注册的回调函数,queue用于记录路由历史记录,可以被当作一个路由队列。

    编辑 (opens new window)
    上次更新: 2025/04/09, 10:15:29
    《Vue3源码》笔记
    pinia-plugin-persistedstate源码浅析

    ← 《Vue3源码》笔记 pinia-plugin-persistedstate源码浅析→

    最近更新
    01
    GeoJSON
    05-08
    02
    Circle
    04-15
    03
    CircleMarker
    04-15
    更多文章>
    Theme by Vdoing | Copyright © 2024-2025 东流 | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式