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处 ...
随机推荐
- python daal test
import os import sys from daal.algorithms import low_order_moments from daal.data_management import ...
- ES批量索引写入时的ID自动生成算法
对bulk request的处理流程: 1.遍历所有的request,对其做一些加工,主要包括:获取routing(如果mapping里有的话).指定的timestamp(如果没有带timestamp ...
- Mac自带的本地服务器的使用
1. 打开终端,开启Apache: //开启apache: sudo apachectl start //重启apache: sudo apachectl restart //关闭apache: su ...
- Oracle11g dump 部分参数解读
一.Oracle dump expdp CONTENT ALL ALL ,将导出对象定义及其所有数据 DATA_ONLY DATA_ONLY,只导出对象数据 METADATA_ONLY ...
- 《Python》 内置函数
一.内置函数: Python给你提供的,拿来直接用的函数,比如print.input等等,就是内置函数. 截止到Python版本3.6.2,现在Python一共为我们提供了68个内置函数. ...
- Python的generator生成器
generator保存的是算法,元素仅在使用的时候生成,占用内存小,总元素的个数可以是无限个. 简单的生成器与列表生成式,区别仅在于将中括号[ ],换成小圆括号( ). In [1]: g=(x*x+ ...
- 用UILabel实现文字滚动播放(跑马灯)效果
- (void)viewDidLoad { [super viewDidLoad]; //数据源 self.messageArray = [NSArray arrayWithObjects: &quo ...
- srtvlet filter
Filter,过滤器,顾名思义,即是对数据等的过滤,预处理过程.为什么要引入过滤器呢?在平常访问网站的时候,有时候发一些敏感的信息,发出后显示时 就会将敏感信息用*等字符替代,这就是用过滤器对信息进行 ...
- [C#] 网站程序ASP.NET的性能诊断 - CPU分析
微软提供了标准的CLR性能分析类库 https://github.com/Microsoft/clrmd 这个类库是开源的代码.能够获取CLR runtime里面几乎所有的信息. 如何获取clrmd编 ...
- SIM800C 使用基站定位
/******************************************************************************* * SIM800C 使用基站定位 * ...