vue-router是怎么实现的?
Posted evaling
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue-router是怎么实现的?相关的知识,希望对你有一定的参考价值。
路由响应过程:
-
浏览器发出请求
-
服务器监听到num端口(或443)有请求过来,并解析url路径
-
-
浏览器根据数据包的 Content-Type 来决定如何解析数据
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() })
在使用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)
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}`) } }
(源码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) { 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中的索引 }
https://segmentfault.com/a/1190000015123061
以上是关于vue-router是怎么实现的?的主要内容,如果未能解决你的问题,请参考以下文章
vue-router组件里面点击一个按钮跳转到一个新的组件该怎么实现