vue-router 结合源码分析原理
路由响应过程:
浏览器发出请求
服务器监听到num端口(或443)有请求过来,并解析url路径
根据服务器的路由配置,返回相应信息(可以是 html 字串,也可以是 json 数据,图片等)
浏览器根据数据包的 Content-Type 来决定如何解析数据
一般的vueRouter的代码模式是这样的:
let router = new Router({
mode: 'history|hash|abstract',
routes: [
{ // 默认页
path: '*',
redirect: to => {
return '/'
},
meta: {
status: ***
}
},
{
path: '/',
name: '****',
component: ****,
meta: {
status: ***
}
},
],
beforeEnter: (to, from, next) => {}),
scrollBehavior: fun()
})
可以看到的是使用Router这个类进行实例化【new Router(options)】
在使用vueRouter的时候,我们会在项目中使用Vue.use(Router)安装,它会加载VueRouter中的 install 方法使得所有组件都可以使用router的实例(this.$router/this.$route) 在install的时候实际上完成一些初始化的工作
(源码install.js)
1)在vue.prototype上注册一个$router/$route的实例
Vue.mixin({
beforeCreate () {
if (isDef(this.$options.router)) {
this._routerRoot = this
this._router = this.$options.router
Object.defineProperty(Vue.prototype, '$router', {
get () { return this._routerRoot._router }
})
Object.defineProperty(Vue.prototype, '$route', {
get () { return this._routerRoot._route }
})
2)全局注册RouterView, RouterLink这两个组件
Vue.component('RouterView', View)
Vue.component('RouterLink', Link)
分为三种模式: hash, history(h5), abstract
(源码index.js)
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}`)
}
}
三种模式的简单描述:
a)hash
常见形式:http(https)://xxxxxx/#/xxxx
在h5之前浏览器不支持popState(window),pushState(history)和 replaceState(history)这几个事件,因此是通过hash值来改变路由,后面 hash 值的变化,并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。另外每次 hash 值的变化,还会触发hashchange 这个事件,通过这个事件我们就可以知道 hash 值发生了哪些变化。然后我们便可以监听hashchange来实现更新页面部分内容的操作:
(源码hash.js)
// supportsPushState用于用于判断浏览器是否支持h5
window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', () => {
const current = this.current
if (!ensureSlash()) {
return
}
this.transitionTo(getHash(), route => {
if (supportsScroll) {
handleScroll(this.router, route, current, true)
}
if (!supportsPushState) { // 如果不支持pushState 就使用window.location.replace(getUrl(path))
replaceHash(route.fullPath)
}
})
})
b)history
在h5之后,得到浏览器的支持就可以使用history模式了,在history模式下路由的改变会触发popstate事件,因此history模式原理也是对popstate事件的监听,然后做出相应操作。
(源码html5.js)
window.addEventListener('popstate', e => {
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 === initLocation) {
return
}
this.transitionTo(location, route => {
if (supportsScroll) {
handleScroll(router, route, current, true)
}
})
})
c)abstract
abstract 模式是用于原生开发(非浏览器typeof window=== 'undefined')的情况下,这就意味着不能使用window对象;另外由于在原生app中,页面储存一个数组栈中,它记录着页面的的访问记录,因此在js中最简单的就是定义数组进行模仿。
(源码abstrack.js)
constructor (router: Router, base: ?string) {
super(router, base)
this.stack = [] // 定义一个stack数组,用于存储路由
this.index = -1 // 记录每个路由在stack中的索引
}
关于popstate,pushState, replaceState:
1)window.popstate,history.pushState,history.replaceState是h5中新增的几个方法。
2)hash模式情况下路由的该变会触发window.hashtate,history模式下会触发window.popstate事件。
3)history.pushState()/replaceState() 会修改url ,不会使得页面更新,也不会触发window.popstate事件。
在history模式下使得页面url与代码中路由地址相同
4)history.back() /go(),window.location.hash 都会使得页面改变,触发window.popstate事件。
对此事件进行拦截处理一些事情(参数接收,页面位置记录)
window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', () => {
const current = this.current
if (!ensureSlash()) {
return
}
this.transitionTo(getHash(), route => {
if (supportsScroll) {
handleScroll(this.router, route, current, true)
}
if (!supportsPushState) {
replaceHash(route.fullPath)
}
})
})
5)使用导航的时候其实都是使用的 this.history.push()/ go() /replace() 进行页面切换。
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)
}
go (n: number) {
this.history.go(n)
}
back () {
this.go(-1)
}
forward () {
this.go(1)
}
https://segmentfault.com/a/1190000015123061
https://zhuanlan.zhihu.com/p/24574970
vue-router 结合源码分析原理的更多相关文章
- 从vue.js的源码分析,input和textarea上的v-model指令到底做了什么
v-model是 vue.js 中用于在表单表单元素上创建双向数据绑定,它的本质只是一个语法糖,在单向数据绑定的基础上,增加了监听用户输入事件并更新数据的功能:对,它本质上只是一个语法糖,但到底是一个 ...
- koa2中间件koa和koa-compose源码分析原理(一)
koa是基于nodejs平台的下一代web开发框架,它是使用generator和promise,koa的中间件是一系列generator函数的对象.当对象被请求过来的时候,会依次经过各个中间件进行处理 ...
- Vue.js 源码分析(七) 基础篇 侦听器 watch属性详解
先来看看官网的介绍: 官网介绍的很好理解了,也就是监听一个数据的变化,当该数据变化时执行我们的watch方法,watch选项是一个对象,键为需要观察的数据名,值为一个表达式(函数),还可以是一个对象, ...
- 【转载】Android异步消息处理机制详解及源码分析
PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...
- vue双向绑定的原理及实现双向绑定MVVM源码分析
vue双向绑定的原理及实现双向绑定MVVM源码分析 双向数据绑定的原理是:可以将对象的属性绑定到UI,具体的说,我们有一个对象,该对象有一个name属性,当我们给这个对象name属性赋新值的时候,新值 ...
- [Vue源码分析] v-model实现原理
最近小组有个关于vue源码分析的分享会,提前准备一下… 前言:我们都知道使用v-model可以实现数据的双向绑定,及实现数据的变化驱动dom的更新,dom的更新影响数据的变化.那么v-model是怎么 ...
- Vue.js 源码分析(四) 基础篇 响应式原理 data属性
官网对data属性的介绍如下: 意思就是:data保存着Vue实例里用到的数据,Vue会修改data里的每个属性的访问控制器属性,当访问每个属性时会访问对应的get方法,修改属性时会执行对应的set方 ...
- Vue.js 源码分析(二十七) 高级应用 异步组件 详解
当我们的项目足够大,使用的组件就会很多,此时如果一次性加载所有的组件是比较花费时间的.一开始就把所有的组件都加载是没必要的一笔开销,此时可以用异步组件来优化一下. 异步组件简单的说就是只有等到在页面里 ...
- 前端Vue 源码分析-逻辑层
Vue 源码分析-逻辑层 预期的效果: 监听input的输入,input在输入的时候,会触发 watch与computed函数,并且会更新原始的input的数值.所以直接跟input相关的处理就有3处 ...
随机推荐
- java.net.SocketException: Broken pipe
java.net.SocketException: Broken pipe 生产上遇到一个问题,socket发生Broken pipe错误,如下 这个问题跟踪了好几个月,始终没有模拟出为什么会发生Br ...
- 用Maven构建Mahout项目
转载请注明出处:http://blog.fens.me/hadoop-mahout-maven-eclipse/ Hadoop家族系列文章,主要介绍Hadoop家族产品,常用的项目包括Hadoop, ...
- notepad++插件安装
notepad安装目录的 plugins 下重启 notepad.exe程序即可 插件下载地址 : https://sourceforge.net/projects/npp-plugins/fil ...
- DevExpress v17.2新版亮点—.NET Reporting篇(一)
用户界面套包DevExpress v17.2日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容.本文将介绍了.NET Reporting v17.2 的新功能,快来下载试用新版本! All ...
- RNN - LSTM - GRU
循环神经网络 (Recurrent Neural Network,RNN) 是一类具有短期记忆能力的神经网络,因而常用于序列建模.本篇先总结 RNN 的基本概念,以及其训练中时常遇到梯度爆炸和梯度消失 ...
- JDBC事务控制管理(转载)
JDBC事务控制管理 转载于 2018年01月26日 15:46:11 1.事务 (1)事务的概念 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 例如:A——B转帐, ...
- Android shell command execute Demo
package com.android.utils; import java.io.File; import java.io.IOException; import java.io.InputStre ...
- 将Mat类型坐标数据生成pts文件
前言 获取人脸特征点的坐标信息之后,想要将坐标信息shape保存为pts/asf/txt等文件格式,本文就对此进行实现. 实现过程 1.确定pts文件的书写格式: 以要生成的文件为例,书写格式如下: ...
- led不同颜色的驱动电压和驱动电流
LED耗电非常低,一般来说LED的工作电压是2-3.6V,其中红光电压是1.8-2.1V 波长610-620 绿光电压是3.0-3.5V 波长520-530 兰光电压是3.0-3.5V 波长 ...
- HDU 3342:Legal or Not(拓扑排序)
Legal or Not Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...