目录

  • 一、概念
  • 二、两种实现方式
    • 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. python绘制如下图形、小三角形边长20_在编程中发现数学之美——使用Python小龟绘制多边形...
  2. 每次digital painting 之后,都可以把作品放到这里,比较好看,也和nft相关度比较大
  3. centos6.5 yum安装mysql_CentOS 6.5使用yum安装MySQL快速上手必备
  4. 选课网站html源码,选课系统网页制作(26页)-原创力文档
  5. C#网络编程概述 三
  6. 送书丨《架构解密:从分布式到微服务》
  7. Trie 树内存消耗问题
  8. 如何使用迅雷下载百度网盘资源
  9. CVonline: Image Databases
  10. 阿里云服务器哪个便宜?
  11. 正当防卫指导性案例以及研析
  12. Diy-Scratch(4) 大家来找茬
  13. grafana配置alert
  14. opencv图像形态学运算
  15. 敏捷开发“松结对编程”实践之三:共同估算篇(大型研发团队,学习型团队,139团队,师徒制度,敏捷设计,估算扑克,扑克牌估算) .
  16. 算法总结——大整数乘法
  17. 算法系统下的外卖平台:饿了么可选多等5分钟,美团无差别8分钟
  18. 如何营造沉浸式实景演艺旅游环境
  19. 快手__nsTokensig和sig签名算法分析
  20. FOC之Clarke变换和Park变换

热门文章

  1. 人工智能与设计的未来趋势,人工智能和建筑设计
  2. 2018伦敦全球电信大奖回顾,华为斩获5G先锋“全球大奖, 并携手中国移动香港荣获“云化先锋”奖!
  3. CSDN编程竞赛 ——— 第十期
  4. AStyle使用小结
  5. 射频安全-记一次无线钥匙射频信号分析(未果)
  6. 前序、中序和后序表达式转换问题
  7. 气泡shader_5,Raymarching in UE4(气泡材质)
  8. 达摩院公布:2022十大科技趋势发布,我一个都看不懂!
  9. Asp.Net SignalR Hub集线器
  10. Linux操作(vi编辑器)