Vue Router 路由实现原理
目录
- 一、概念
- 二、两种实现方式
- 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
获取。
特点
- 通过hash方式的,路由地址会有
#
举例:
http://localhost:8080/#/a
- #后面的内容不会传给服务端,也就是说不会重新刷新页面。并且路由切换的时候也不会重新加载页面。
因此改变hash不会重新加载页面
- 每一次改变
hash(window.localtion.hash)
,都会在浏览器访问历史中增加一个记录。
举例:
http://localhost:8080/#/a
//变为 如下地址,浏览器访问历史中会增加一个记录
http://localhost:8080/#/b
- 可以为 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()
三、两种模式比较
pushState设置的新的URL可以是与当前URL同源的任意URL;而hash只可修改
#
后边的部分,故只可设置与当前文档同文档的URLpushState通过stateObject可以添加任意类型的数据到记录中;而hash只可添加短字符串
pushState可额外设置title属性后供后续使用
history模式则会将URL修改得就和正常请求后端的URL一样,如后端没有配置对应/user/id的路由处理,则会返回404错误
Vue Router 路由实现原理相关推荐
- Vue 学习(十、 Vue Router - 路由插件 和 Vue 的插件原理)
文章目录 一.Vue Router - 路由插件 1. 安装 Vue Router 2. Vue Router 路由的基本使用 3. 设置 router-link 4. 编程式路由 5. 路由嵌套 6 ...
- vue页面路由的原理
47. vue页面路由的原理 1. 原理 Vue 中的路由原理是基于浏览器的 history API 和 Vue 的路由插件 Vue Router 实现的. 具体来说,当浏览器接收到一个新的路由请求时 ...
- Vue Router 路由管理
文章目录 Vue Router 路由管理 概述 安装 简单使用 定义2个组件 定义路由信息 支持路由 使用路由 动态路由 配置动态路由 配置404 限制动态参数 嵌套路由 命名路由 编程式导航 简单使 ...
- 【Vue】相关生态——Vue Router路由
Vue Router路由 基本使用 带参数的动态路由匹配 捕获所有路由或404 Not found 路由 嵌套路由 编程式导航 重定向和别名 将props传递给路由组件 不同的历史模式 进阶 导航守卫 ...
- Vue Router路由常用功能总结
Vue Router路由常用功能总结 一.前言 二.安装 1. vueCLI安装 2. npm安装 三.路由配置及使用: 1. 基本配置: 2. 动态路由: 3. 嵌套路由: 四.编程式的导航 五.重 ...
- Vue的路由实现原理解析(最清晰)
Vue的路由实现原理解析(最清晰) 一般源码中,都会用到 window.history 和 location.hash history 实现 window.history 对象包含浏览器的历史,win ...
- Vue.js 3.0 学习笔记(十一)Vue Router路由
一.使用Vue Router 1.HTML页面使用路由 <!DOCTYPE html> <html> <head><meta charset="UT ...
- Vue | Vue Router 路由的使用
文章目录 一.路由的基本使用 1.创建 Vue 项目并引入 vue-router 2.编写 Components 组件 3.编写路由文件 4.在主文件 Main.js 中引入路由 5.添加 route ...
- Vue Router 路由导航
Vue Router 通过 Vue.js,我们已经用组件组成了我们的应用.当加入 Vue Router 时,我们需要做的就是将我们的组件映射到路由上,让 Vue Router 知道在哪里渲染它们. V ...
最新文章
- python绘制如下图形、小三角形边长20_在编程中发现数学之美——使用Python小龟绘制多边形...
- 每次digital painting 之后,都可以把作品放到这里,比较好看,也和nft相关度比较大
- centos6.5 yum安装mysql_CentOS 6.5使用yum安装MySQL快速上手必备
- 选课网站html源码,选课系统网页制作(26页)-原创力文档
- C#网络编程概述 三
- 送书丨《架构解密:从分布式到微服务》
- Trie 树内存消耗问题
- 如何使用迅雷下载百度网盘资源
- CVonline: Image Databases
- 阿里云服务器哪个便宜?
- 正当防卫指导性案例以及研析
- Diy-Scratch(4) 大家来找茬
- grafana配置alert
- opencv图像形态学运算
- 敏捷开发“松结对编程”实践之三:共同估算篇(大型研发团队,学习型团队,139团队,师徒制度,敏捷设计,估算扑克,扑克牌估算) .
- 算法总结——大整数乘法
- 算法系统下的外卖平台:饿了么可选多等5分钟,美团无差别8分钟
- 如何营造沉浸式实景演艺旅游环境
- 快手__nsTokensig和sig签名算法分析
- FOC之Clarke变换和Park变换
热门文章
- 人工智能与设计的未来趋势,人工智能和建筑设计
- 2018伦敦全球电信大奖回顾,华为斩获5G先锋“全球大奖, 并携手中国移动香港荣获“云化先锋”奖!
- CSDN编程竞赛 ——— 第十期
- AStyle使用小结
- 射频安全-记一次无线钥匙射频信号分析(未果)
- 前序、中序和后序表达式转换问题
- 气泡shader_5,Raymarching in UE4(气泡材质)
- 达摩院公布:2022十大科技趋势发布,我一个都看不懂!
- Asp.Net SignalR Hub集线器
- Linux操作(vi编辑器)