目录

  • 一、概念
  • 二、两种实现方式
    • HashHistory
      • 简介
      • 特点
      • 方法
        • HashHistory.push()
        • HashHistory.replace()
    • HTML5History
      • 简介
      • 特点
      • 方法
        • history.pushState()
        • history.replaceState()
  • 三、两种模式比较

一、概念

通过改变URL,在不重新请求页面的情况下,更新页面视图。

二、两种实现方式

更新视图但不重新请求页面,是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有2种方式:

  • Hash—利用URL中的hash(“#”);
  • 利用History interface在HTML5中新增的方法。

mode参数

Vue中,通过mode这一参数来决定采用哪一种方式,选择流程如下:

  • 默认为hash

  • 使用history时,进行如下设置(如果浏览器比支持history新特性,则采用hash方式)

const router=new VueRouter({mode:'history',//设置路由实现方式为historyroutes:[...]
})
  • 如果不在浏览器环境下则使用abstract(node环境下)

创建VueRouter的实例对象时,mode以构造参数的形式传入,如下代码:

src/index.jsexport default class VueRouter{mode: string; // 传入的字符串参数,指示history类别history: HashHistory | HTML5History | AbstractHistory; // 实际起作用的对象属性,必须是以上三个类的枚举fallback: boolean; // 如浏览器不支持,'history'模式需回滚为'hash'模式constructor (options: RouterOptions = {}) {let mode = options.mode || 'hash' // 默认为'hash'模式this.fallback = mode === 'history' && !supportsPushState // 通过supportsPushState判断浏览器是否支持'history'模式if (this.fallback) {mode = 'hash'}if (!inBrowser) {mode = 'abstract' // 不在浏览器环境下运行需强制为'abstract'模式}this.mode = mode// 根据mode确定history实际的类并实例化switch (mode) {case 'history':this.history = new HTML5History(this, options.base)breakcase 'hash':this.history = new HashHistory(this, options.base, this.fallback)breakcase 'abstract':this.history = new AbstractHistory(this, options.base)breakdefault:if (process.env.NODE_ENV !== 'production') {assert(false, `invalid mode: ${mode}`)}}}init (app: any /* Vue component instance */) {const history = this.history// 根据history的类别执行相应的初始化操作和监听if (history instanceof HTML5History) {history.transitionTo(history.getCurrentLocation())} else if (history instanceof HashHistory) {const setupHashListener = () => {history.setupListeners()}history.transitionTo(history.getCurrentLocation(),setupHashListener,setupHashListener)}history.listen(route => {this.apps.forEach((app) => {app._route = route})})}// VueRouter类暴露的以下方法实际是调用具体history对象的方法push (location: RawLocation, onComplete?: Function, onAbort?: Function) {this.history.push(location, onComplete, onAbort)}replace (location: RawLocation, onComplete?: Function, onAbort?: Function) {this.history.replace(location, onComplete, onAbort)}
}源码

HashHistory

简介

hash(“#”)的作用是加载URL中指示的网页的位置。
#本身以及它后面的字符,可以通过window.location.hash获取。

特点

  1. 通过hash方式的,路由地址会有#
    举例:
http://localhost:8080/#/a
  1. #后面的内容不会传给服务端,也就是说不会重新刷新页面。并且路由切换的时候也不会重新加载页面。因此改变hash不会重新加载页面
  2. 每一次改变 hash(window.localtion.hash),都会在浏览器访问历史中增加一个记录。
    举例:
http://localhost:8080/#/a
//变为 如下地址,浏览器访问历史中会增加一个记录
http://localhost:8080/#/b
  1. 可以为 hash 的改变添加监听事件:
  window.addEventListener("hashchange",funcRef,false)  

利用hash的以上特点,就可以来实现“前端路由”更新视图但不重新请求页面的功能了。

方法

HashHistory 拥有两个方法,一个是HashHistory.push(), 一个是HashHistory.replace()

HashHistory.push()

将路由添加到浏览器访问历史的栈顶

如图:

从设置路由改变到视图更新的流程:

$router.push() --> HashHistory.push() --> History.transitionTo() --> History.updateRoute() --> {app._route = route} --> vm.render()

详解:

$router.push() //调用方法
HashHistory.push() //根据hash模式调用,设置hash并添加到浏览器历史记录(添加到栈顶)(window.location.hash = XXX)
History.transitionTo() //监测更新,更新则调用History.updateRoute()
History.updateRoute() //更新路由
{app._route= route} //
vm.render() //更新视图

HashHistory.replace()

replace()方法与push()方法不同之处在于,他并不是将新路由添加到浏览器访问历史的栈顶,而是替换掉当前路由。

如图:

HTML5History

简介

History interface是浏览器历史记录栈提供的接口,通过back()forward()go()等方法,我们可以读取浏览器历史记录栈的信息,进行各种跳转操作。

从Html5开始,History interface提供了两个新的方法:pushState(),replaceState()提供了2个新方法:pushState(),replaceState()使得我们可以对浏览器历史记录栈进行修改:

window.history.pushState(stateObject,title,url)window.history,replaceState(stateObject,title,url)

参数分析:

  • stateObject:当浏览器跳转到新的状态时,将触发Popstate事件,该事件将携带这个stateObject参数的副本
  • title:所添加记录的标题
  • url:所添加记录的url

特点

  • 通过history模式,实现单页路由的URL没有# ,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。
http://localhost:8080/a
  • 为了避免这种情况,所以history路由实现方式需要服务器的支持,需要把所有的路由都定向到根页面。

  • 在HTML5History的构造函数中监听使用popState(window.onpopstate)

方法

history.pushState()

与hash模式类似,只是将window.hash()改为history.pushState()

history.replaceState()

与hash模式类似,只是将window.replace()改为history.replaceState()

三、两种模式比较

  1. pushState设置的新的URL可以是与当前URL同源的任意URL;而hash只可修改#后边的部分,故只可设置与当前文档同文档的URL

  2. pushState通过stateObject可以添加任意类型的数据到记录中;而hash只可添加短字符串

  3. pushState可额外设置title属性后供后续使用

  4. history模式则会将URL修改得就和正常请求后端的URL一样,如后端没有配置对应/user/id的路由处理,则会返回404错误

Vue Router 路由实现原理相关推荐

  1. Vue 学习(十、 Vue Router - 路由插件 和 Vue 的插件原理)

    文章目录 一.Vue Router - 路由插件 1. 安装 Vue Router 2. Vue Router 路由的基本使用 3. 设置 router-link 4. 编程式路由 5. 路由嵌套 6 ...

  2. vue页面路由的原理

    47. vue页面路由的原理 1. 原理 Vue 中的路由原理是基于浏览器的 history API 和 Vue 的路由插件 Vue Router 实现的. 具体来说,当浏览器接收到一个新的路由请求时 ...

  3. Vue Router 路由管理

    文章目录 Vue Router 路由管理 概述 安装 简单使用 定义2个组件 定义路由信息 支持路由 使用路由 动态路由 配置动态路由 配置404 限制动态参数 嵌套路由 命名路由 编程式导航 简单使 ...

  4. 【Vue】相关生态——Vue Router路由

    Vue Router路由 基本使用 带参数的动态路由匹配 捕获所有路由或404 Not found 路由 嵌套路由 编程式导航 重定向和别名 将props传递给路由组件 不同的历史模式 进阶 导航守卫 ...

  5. Vue Router路由常用功能总结

    Vue Router路由常用功能总结 一.前言 二.安装 1. vueCLI安装 2. npm安装 三.路由配置及使用: 1. 基本配置: 2. 动态路由: 3. 嵌套路由: 四.编程式的导航 五.重 ...

  6. Vue的路由实现原理解析(最清晰)

    Vue的路由实现原理解析(最清晰) 一般源码中,都会用到 window.history 和 location.hash history 实现 window.history 对象包含浏览器的历史,win ...

  7. Vue.js 3.0 学习笔记(十一)Vue Router路由

    一.使用Vue Router 1.HTML页面使用路由 <!DOCTYPE html> <html> <head><meta charset="UT ...

  8. Vue | Vue Router 路由的使用

    文章目录 一.路由的基本使用 1.创建 Vue 项目并引入 vue-router 2.编写 Components 组件 3.编写路由文件 4.在主文件 Main.js 中引入路由 5.添加 route ...

  9. Vue Router 路由导航

    Vue Router 通过 Vue.js,我们已经用组件组成了我们的应用.当加入 Vue Router 时,我们需要做的就是将我们的组件映射到路由上,让 Vue Router 知道在哪里渲染它们. V ...

最新文章

  1. 三星android功能怎么用,三星GALAXY S II升级Android 4.0新功能介绍及使用技巧
  2. 配置远程服务器jupyter
  3. asp动态树菜单集合(3/3)
  4. python opengl 截图_初试PyOpenGL二 (Python+OpenGL)基本地形生成与高度检测
  5. 云端点保护解决方案行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  6. ASP.NET——C#文件夹创建与文件存在判断
  7. js给列表设置统一的高度
  8. 吸毒女5次搬家躲粉友:想给女儿干净环境
  9. 利用selenium框架爬取京东省市区数据时,网页里面内嵌的一个窗口遇到的NoSuchElementException的 bug,原因是iframe
  10. Windows 技术篇-修改hosts添加域名解析实例演示,设置域名指定ip方法
  11. 「Vue实战」武装你的前端项目
  12. 固网服务器win7系统驱动,固网HU-1608n驱动
  13. ORACLE 掐头去尾截取中间字符串
  14. MSXML2.DOMDocument
  15. 【数学】母函数(生成函数)的性质及应用
  16. 可视化工具VisIt安装使用教程(Windows)
  17. 【代码】第11章 APP的爬取,appium打开微信朋友圈
  18. 攻防世界-pwn-forgot
  19. IAR STM32 函数和变量的绝对地址定位
  20. python爬取文献代码_爬取Pubmed文献及影响因子并尝试下载的脚本

热门文章

  1. Threatbook合伙人李秋石:具有中国特色的安全威胁情报
  2. markdown 让你快速无痛学会编写IT文档
  3. 机器学习中的线性代数
  4. 程序员学英语要避免这几个坑
  5. 计算机二级考试c语言程序填空题,计算机二级C语言练习题:程序填空题
  6. 二叉树顺序存储-实现前序中序后序遍历
  7. 链游、元宇宙、GameFi和NFT之间的关系
  8. [Java教程 01]Hello,Java!
  9. 大连东软信息学院linux系统编程,大连东软信息学院Linux系统编程考试资料
  10. oppo安卓面试题,Android基础开发与实践