vue-router路由实现原理

Vue-Router的Hash模式简介与分析 Vue-Router是Vue.js官方推荐的路由管理器,用于构建单页应用程序(SPA)。它允许我们在Vue应用中实现路由功能,从而实现页面之间的无刷新切换。Vue-Router提供了多种路由模式,其中之一是Hash模式。Hash模式是Vue-Router的默认路由模式,它通过URL的哈希(#)来管理路由。当URL的哈希发生变化时,Vue-Router会根据哈希值来匹配对应的路由,并加载相应的组件。 阅读详情

通常我们使用Vue来开发单页面应用(SPA)时,通常都会使用vue-router来实现页面路由跳转。单页面应用采用前端路由系统,通过改变URL,在不重新请求页面的情况下,更新页面视图。
Vue-router提供了以下几种路由跳转方法

方法作用
router.push添加新路由
router.replace替换当前路由
router.go跳转到指定索引路由
router.back返回上一个路由
router.forward跳转下一个路由

下面我们通过vue-router源码来了解实现原理:

模式参数
通常通过mode参数来指定模式,默认为hash模式,代码中明确指定mode为history时为history模式

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

下面我们来看VueRouter类的代码

export default class VueRouter {
  static install: () => void
  static version: string
  static isNavigationFailure: Function
  static NavigationFailureType: any

  app: any
  apps: Array<any>
  ready: boolean
  readyCbs: Array<Function>
  options: RouterOptions
  mode: string
  history: HashHistory | HTML5History | AbstractHistory
  matcher: Matcher
  fallback: boolean
  beforeHooks: Array<?NavigationGuard>
  resolveHooks: Array<?NavigationGuard>
  afterHooks: Array<?AfterNavigationHook>

  constructor (options: RouterOptions = {}) {
    this.app = null
    this.apps = []
    this.options = options
    this.beforeHooks = []
    this.resolveHooks = []
    this.afterHooks = []
    this.matcher = createMatcher(options.routes || [], this)

    let mode = options.mode || 'hash'
    this.fallback =
      mode === 'history' && !supportsPushState && options.fallback !== false
    if (this.fallback) {
      mode = 'hash'
    }
    if (!inBrowser) {
      mode = 'abstract'
    }
    this.mode = mode

    switch (mode) {
      case 'history':
        this.history = new HTML5History(this, options.base)
        break
      case 'hash':
        this.history = new HashHistory(this, options.base, this.fallback)
        break
      case 'abstract':
        this.history = new AbstractHistory(this, options.base)
        break
      default:
        if (process.env.NODE_ENV !== 'production') {
          assert(false, `invalid mode: ${mode}`)
        }
    }
  }

constructor构造方法中,通过判断传入的mode参数来初始化history属性

modehistory
historyHTML5History
hashHashHistory
abstractAbstractHistory

初始化之前,会对mode做校验,如果浏览器不支持HTML5History方式,会强制修改模式为hash;如果不是在浏览器里面运行的,会强制修改模式为abstract

hash和history两种模式的主要区别是push和replace实现原理的区别,下面详细分析具体实现原理:

hashHistory
浏览器地址栏URL中的#则为hash,我们可以通过window.location.hash来获取hash值,通常带有hash值得URL类似于这样:http://www.xx.x/index.html#test

hash值有以下几个特点:

  • hash虽然包含在URL中,但不会被包括在HTTP请求中。它是用来指导浏览器动作的,对服务器端完全无用,因此,改变hash不会重新加载页面
  • 可以添加用于监听hash值变化的事件
window.addEventListener("hashchange", funcRef, false)
  • 每一次改变hash值,都会在浏览器的访问历史中添加一条记录

利用以上几个特点,前端路由可以实现更新视图但不重新请求页面

push()方法的实现

push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
    const { current: fromRoute } = this
    this.transitionTo(
      location,
      route => {
        pushHash(route.fullPath)
        handleScroll(this.router, route, fromRoute, false)
        onComplete && onComplete(route)
      },
      onAbort
    )
  }

function pushHash (path) {
  if (supportsPushState) {
    pushState(getUrl(path))
  } else {
    //直接赋值hash
    window.location.hash = path
  }
}

transitionTo()方法是父类中定义的是用来处理路由变化中的基础逻辑的,push方法主要通过直接对window.location.hash赋值,hash值得改变会自动记录到浏览器访问历史记录中

replace()方法的实现

replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {
    const { current: fromRoute } = this
    this.transitionTo(
      location,
      route => {
        replaceHash(route.fullPath)
        handleScroll(this.router, route, fromRoute, false)
        onComplete && onComplete(route)
      },
      onAbort
    )
  }

function getUrl (path) {
  //window.location.href为浏览器当前URL
  const href = window.location.href
  const i = href.indexOf('#')
  const base = i >= 0 ? href.slice(0, i) : href
  //返回更新hash值后的URL
  return `${base}#${path}`
}
function replaceHash (path) {
  if (supportsPushState) {
    replaceState(getUrl(path))
  } else {
    window.location.replace(getUrl(path))
  }
}

replace()方法中,通过更新当前路由地址中hash值来覆盖当期路由

添加监听事件

setupListeners () {
    if (this.listeners.length > 0) {
      return
    }

    const router = this.router
    const expectScroll = router.options.scrollBehavior
    const supportsScroll = supportsPushState && expectScroll

    if (supportsScroll) {
      this.listeners.push(setupScroll())
    }

    const handleRoutingEvent = () => {
      const current = this.current
      if (!ensureSlash()) {
        return
      }
      this.transitionTo(getHash(), route => {
        if (supportsScroll) {
          handleScroll(this.router, route, current, true)
        }
        if (!supportsPushState) {
          replaceHash(route.fullPath)
        }
      })
    }
    const eventType = supportsPushState ? 'popstate' : 'hashchange'
    window.addEventListener(
      eventType,
      handleRoutingEvent
    )
    this.listeners.push(() => {
      window.removeEventListener(eventType, handleRoutingEvent)
    })
  }

在浏览器中,用户还可以直接在浏览器地址栏中输入改变路由,因此VueRouter还需要能监听浏览器地址栏中路由的变化,并具有与通过代码调用相同的响应行为。

setupListeners()方法设置监听了浏览器事件hashchange,调用的函数为replaceHash,即在浏览器地址栏中直接输入路由相当于代码调用了replace()方法

在这里插入图片描述

HTML5History
history模式通过window.history提供的方法来实现路由跳转

在这里插入图片描述
pushState和replaceState方法修改浏览器历史记录栈后,虽然当前URL改变了,但浏览器不会立即发送请求该URL(the browser won’t attempt to load this URL after a call to pushState()),这就为单页应用前端路由“更新视图但不重新请求页面”提供了基础

push (location: RawLocation, onComplete?: Function, onAbort?: Function) {
    const { current: fromRoute } = this
    this.transitionTo(location, route => {
      pushState(cleanPath(this.base + route.fullPath))
      handleScroll(this.router, route, fromRoute, false)
      onComplete && onComplete(route)
    }, onAbort)
  }
export function pushState (url?: string, replace?: boolean) {
  saveScrollPosition()
  // try...catch the pushState call to get around Safari
  // DOM Exception 18 where it limits to 100 pushState calls
  const history = window.history
  try {
    if (replace) {
      // preserve existing history state as it could be overriden by the user
      const stateCopy = extend({}, history.state)
      stateCopy.key = getStateKey()
      history.replaceState(stateCopy, '', url)
    } else {
      history.pushState({ key: setStateKey(genStateKey()) }, '', url)
    }
  } catch (e) {
    window.location[replace ? 'replace' : 'assign'](url)
  }
}

export function replaceState (url?: string) {
  pushState(url, true)
}

分别通过调用history.pushState()和history.replaceState()方法来实现push和replace方法

setupListeners () {
    if (this.listeners.length > 0) {
      return
    }

    const router = this.router
    const expectScroll = router.options.scrollBehavior
    const supportsScroll = supportsPushState && expectScroll

    if (supportsScroll) {
      this.listeners.push(setupScroll())
    }

    const handleRoutingEvent = () => {
      const current = this.current

      // Avoiding first `popstate` event dispatched in some browsers but first
      // history route not updated since async guard at the same time.
      const location = getLocation(this.base)
      if (this.current === START && location === this._startLocation) {
        return
      }

      this.transitionTo(location, route => {
        if (supportsScroll) {
          handleScroll(router, route, current, true)
        }
      })
    }
    window.addEventListener('popstate', handleRoutingEvent)
    this.listeners.push(() => {
      window.removeEventListener('popstate', handleRoutingEvent)
    })
  }

hash和history模式go、back和forward
两种模式的go、back和forward三个方法都是通过window.history.go()来实现的
在这里插入图片描述
back和forward通过改变go方法的入参来实现
在这里插入图片描述

abstract模式
vue-router为非浏览器环境准备了一个abstract模式,其原理为用一个数组stack模拟出浏览器历史记录栈的功能

hash和history模式对比

  • hash模式在浏览器地址栏中会带有’#’,可能不是很美观
  • history模式可以设置整个URL,而hash模式只可修改#后面的部分
  • history模式新URL与当前URL一样的情况下也会把记录添加到栈中;而hash模式只有设置的新值必须与原来不一样才会触发记录添加到栈中
  • history模式可以添加任意类型的数据到记录中,而hash模式只能添加短字符串
  • history模式可额外设置title属性供后续使用
  • history模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问不存在的地址时就会返回 404,这就不好看了,具体配置可以参考官方文档链接
Vue Router 实现路由跳转和页面渲染的原理及示例代码 Vue Router 是 Vue.js 官方提供的路由管理器,用于实现单页面应用(SPA)中的路由跳转和页面渲染。当用户在应用程序中进行路由跳转时,Vue Router 会根据当前的路径匹配路由表中的路由信息,然后渲染对应的组件。当路由跳转匹配到某个路由时,Vue Router 会创建该路由对应的组件实例,并将其渲染到指定的位置。除了基本的路由跳转和页面渲染外,Vue Router 还提供了更多的功能,如嵌套路由、路由参数、路由守卫等。通过上述代码,我们实现了简单的路由跳转和页面渲染。 阅读详情

相关推荐

HyperLPR3车牌识别-Android-SDK光速部署与使用

基于深度学习高性能中文车牌识别 High Performance Chinese License Plate Recognition Framework.快速部署AndroidSDK

tunm 6117

Vue router 模式 hash 和 history

目录 hash 模式 Vue-router hash history 模式 Vue-router传参 在浏览器中改变地址栏url,将会触发页面资源的重新加载,这使得我们可以在不同的页面间进行跳转,得以浏览不同的内容。但随着单页应用的增多,越来越多的网站采用ajax来加载资源。因为异步加载的特性,地址栏上的资源路径没有被改变,随之而来的问题就是页面的状态无法被保存。这导致我们难以通过熟悉的方式(点击浏览器前进/后退按钮),在前后的页面状态间进行切换。 为...

weixin_42754922的博客 3945

SAP FI实战入门:从借贷法则到F-02记账,新手必懂的会计凭证操作

本文详细介绍了SAP FI模块中借贷记账法的核心逻辑及F-02凭证录入的全流程操作。通过实例解析借贷方向规则、科目编码设置及金额镜像原则,帮助新手快速掌握会计凭证操作技巧。同时提供了FS10N余额查询和常见错误排查方法,助力用户高效完成SAP财务记账任务。

weixin_29306571的博客 261

Vue Router 路由实现原理

目录一、概念二、两种实现方式HashHistory简介特点方法HashHistory.push()HashHistory.replace()HTML5History简介特点方法history.pushState()history.replaceState()三、两种模式比较 一、概念 通过改变URL,在不重新请求页面的情况下,更新页面视图。 二、两种实现方式 更新视图但不重新请求页面,是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有2种方式: Hash—利用URL中的hash(“#”);

weixin_52148548的博客 1530

国产HDMI2.0芯片GSV2011怎么选?手把手教你用它设计音视频采集卡(附FPGA/海思对接指南)

本文详细解析国产HDMI2.0芯片GSV2011在音视频采集卡设计中的应用,涵盖芯片选型、硬件设计要点及与FPGA/海思平台的对接指南。GSV2011凭借4K@60Hz支持、音频提取嵌入功能和高集成度,成为音视频设备的核心选择,助力开发者快速实现高性能采集卡设计。

weixin_30181209的博客 331

硬件笔记——HDMI接口

HDMI可以同时传输视频信号、音频信号和控制信号。其中高速信号有四组:从Data TX到Data RX有3组差分数据信号(TMDS_DATA0~2)和一组差分时钟信号(TMDS_CLOCK)。以及若干低速线。脚编号信号名称信号类型功能说明1热插拔检测连接状态检测。接收端通过此引脚向源端发送高电平信号,通知其已连接并可以开始读取EDID。2UTILITY车载用途悬空3TMDS数据通道2差分信号正极,用于传输视频像素、音频和数据包。4TMDS数据2屏蔽。

2501_94625908的博客 537

vue-router 中常用的 hash 和 history 路由模式实现原理

需要注意的是,在使用 History 模式时,需要确保服务器端配置正确,因为直接访问 URL 时,服务器需要返回对应的 HTML 文件,否则会导致 404 错误。当用户点击链接或执行 JavaScript 代码改变页面 URL 时,Vue-Router 会调用浏览器的。这样就可以实现在 URL 改变时,无需刷新页面就能渲染相应的组件。实现原理:History 模式利用了 HTML5 中的 History API,包括。事件,并根据 URL 中的 hash 值来匹配对应的路由,然后渲染相应的组件。

weixin_59525879的博客 336

手把手教你使用HFSS仿真高速差分过孔—上

高速数字电路设计中,信号完整性是一个非常重要的问题。为了使信号保持良好的传输特性,PCB板上的互联线一般都采用均匀传输线,使互联线保持特性阻抗一致性,减少信号反射。然而PCB板上的互联线很多时候避免不了换层的问题,这时候就必须使用过孔。过孔会导致阻抗不连续,进而造成反射,出现信号完整性问题。         当信号传输速率越高,信号前沿越短的时候,过孔引入的信号完整性问题越严重,需要对过孔进行优

a2447944219的博客 2万+

vue-router中Hash模式和History模式

vue-router 中hash模式和history模式 在vue的路由配置中有mode选项,最直观的区别就是在url中hash 带了一个很丑的 # ,而history是没有#的。vue默认使用hash。 从用户角度看 前端路由实现了两个功能(使用ajax更新页面状态的情况下) 1、记录当前页面的状态(保存或分享当前页的url,再次打开该url时,网页还是保存的(分享)时的状态); 2、可是使用浏览器的前进后退功能(如点击后退按钮,可以使页面回到ajax更新页面之前的状态,url也回到之前的状态) 作为开

老电影故事的博客 8126

基于PyTorch的BP神经网络PID控制器动态调参实战

本文详细介绍了基于PyTorch的BP神经网络PID控制器动态调参实战,结合BP神经网络的自适应能力和PID控制算法的经典优势,实现工业控制中的高效参数调整。通过PyTorch实现BP-PID融合架构,包括网络设计、损失函数优化及动态调参技巧,显著提升控制性能,适用于温度控制、电机控制等场景。

weixin_29094775的博客 520

CentOS7下Node.js v20+安装与常见依赖库问题解决指南

本文详细介绍了在CentOS7系统下安装Node.js v20+的完整流程及常见依赖库问题的解决方案。通过升级glibc到2.28+、配置环境变量以及处理libstdc++版本问题,帮助开发者顺利在老旧系统上部署最新版Node.js,提升开发效率。

weixin_30689307的博客 156

浅析vue-router路由实现原理

前言 通过B站视频和一些童鞋的文章结合GitHub源码阅读来理解路由的实现原理 看过前章vuex状态管理的分享之后,相信对路由这块也是非常感兴趣的,同样的模式,同样的方式,我们走进GitHub之vue-router 同样直接走进 src components:route-link 组件 和 router-view 组件 实现 history:关于浏览器相关,包含 hash模式 , basic...

HiSen的博客 2666

CVPR 2026 即插即用 | 注意力篇 | MSEF:超轻注意力,空间-通道双分支并行融合,既增强特征又抑制噪声!

Multinex提出了一种超轻量级微光图像增强框架,其核心创新是MSEF模块。MSEF采用双分支并行架构,结合空间局部特征(深度可分离卷积)和全局通道注意力(改进SE),通过Tanh激活实现特征增强与抑制。相比传统注意力模块,MSEF在几乎不增加计算量的情况下显著提升性能,特别适合轻量级网络和边缘设备部署。实验表明,该模块能有效提升PSNR约3dB,同时保持极低的参数量(0.7K-45K)。

主要更新底层视觉(去噪、超分等)相关的科研内容,形式为【论文精读】+【论文复现】 603

手写路由Vue-Router源码实现原理

这段代码通过定义VueRouter类和install方法,实现了一个简化版的Vue Router。它允许开发者定义路由规则,并在Vue应用中通过和组件实现页面导航和组件渲染。尽管这个实现相对简单,但它展示了Vue Router的核心概念和工作原理。

m0_74079648的博客 1265

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Vue-Router 动态路由的使用和实现原理

Vue-Router动态路由功能详解:通过定义带参数的路径(如/user/:id),可在组件中用this.$route.params访问参数值。文章介绍了定义动态路由、访问参数的方法,以及使用router.push或<router-link>导航的实现方式。其原理包括路由匹配、参数解析(转为正则表达式)和组件更新机制(复用组件时触发beforeRouteUpdate或$route监听)。该功能适用于用户/文章详情页等需要动态参数的场景,提升应用灵活性。

分享前端工程化、AI 应用、Agent 开发与大模型实践! 693

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

vue-router ——前端路由实现原理

一、什么是前端路由?   前端路由是直接找到与地址匹配的一个组件或对象并将其渲染出来。也就是说,通过改变浏览器地址URL,在不重新请求页面的情况下,更新页面视图 二、单页应用与多页应用 单页应用 即 第一次进入页面的时候会请求一个html文件,刷新清除一下。切换到其他组件,此时路径也相应变化,但是并没有新的html文件请求,页面内容也变化了。 原理:JS会感知到url的变化,通过这一...

FHHHC的博客 216

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

前端路由简介以及vue-router实现原理

后端路由简介 路由这个概念最先是后端出现的。在以前用模板引擎开发页面时,经常会看到这样 http://www.xxx.com/login 大致流程可以看成这样: 浏览器发出请求 服务器监听到80端口(或443)有请求过来,并解析url路径 根据服务器的路由配置,返回相应信息(可以是 html 字串,也可以是 json 数据,图片等) 浏览器根...

dengla6847的博客 534

vue-router 路由实现原理

vue-router 路由实现原理

Fziha的博客 354

Vue Router的路由模式 hash 和 history 的实现原理

Vue Router的路由模式 hash 和 history 的实现原理 1. hash 模式的实现原理: 早期的前端路由的实现就是基于 location.hash 来实现的,其实他的原理很简单, location.hash 的值就是URL中 # 后面的内容 如:[https://www.word.com#search](https://www.word.com#search) 它的location.hash的值是 #search hash 路由模式的实现主要是基于下面几个特点: URL 中的 has

weixin_52688746的博客 3202

vue-router实现单页面路由原理

本文参考总结于: 1、vue-router原理分析 - https://www.cnblogs.com/yanze/p/7644631.html 2、location.hash详解 - http://blog.youkuaiyun.com/baidu_31333625/article/details/54288223 3、使用HTML5的History API - https://www.cnblogs...

github_39532240的博客 1万+

vue获取路由历史_Part3·Vue.js 框架源码与进阶 - Vue-Router 原理实现

1.1Vue-Router 使用步骤yarn add vue-router --dev import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter)样式案例:// view/Blog.vue 路由相关的组件(视图) <template> <div> 这是 Blog 页面...

weixin_35055546的博客 1234

php路由和vue路由的区别,浅析前端路由简介以及vue-router实现原理

路由这个概念最先是后端出现的。在以前用模板引擎开发页面时,经常会看到这样大致流程可以看成这样:浏览器发出请求服务器监听到80端口(或443)有请求过来,并解析url路径根据服务器的路由配置,返回相应信息(可以是 html 字串,也可以是 json 数据,图片等)浏览器根据数据包的 Content-Type 来决定如何解析数据简单来说路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径,来请求...

weixin_28724003的博客 240
上一篇: Vue.use()源码解读
下一篇: Vue项目中render函数的使用
codezha
博客等级 码龄10年 28粉丝 98原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值