欺凌蒂法2,孤枕难眠简谱,ktxp
根据vuerouter的执行流程,可以通过这三个步骤来理解它的设计思想:
vuerouter里的路由有三种模式:
abstract
支持所有 javascript 运行环境,如 node.js 服务器端writer by:大沙漠 qq:22969969
这三种模式有很多共同点,所以vuerouter在实现的时候定义了一个history基类,在基类上定义共同方法,然后再定义三个子类,分别继承整个history类来实现,如下:
class history { //定义一些公共方法,例如跳转操作 } class hashhistory extends history { //hash模式的差异实现,例如获取hash值,设置hash值 } class html5history extends history { //html5模式的差异实现,例如获取当前地址,设置当前地址 } class abstracthistory extends history { //abstract模式的差异实现 }
vuerouter会根据当前的模式,来创建一个对应的history的实例,再在整个实例上进行一系列操作
vuerouter的加载过程
在vuerouter加载的时候,对于浏览器环境它会执行vue.use(vuerouter)自动进行安装,如下:
if (inbrowser && window.vue) { //如果在浏览器环境下且window.vue存在 window.vue.use(vuerouter); //则调用window.vue.use安装vuerouter,此时就会执行install方法 }
vue插件安装的时候就会执行对应的install方法,与加载有关的如下:
function install(vue) { //vue-router的安装方法 /*略*/ vue.mixin({ //混入生命周期函数 注意函数内的上下文是vue实例 beforecreate: function beforecreate() { //beforecreate生命周期函数 if (isdef(this.$options.router)) { //如果this.$options.router存在 ;就是在创建vue实例时传入的router对象 this._routerroot = this; //在vue实例上添加一个_routerroot指向自己,即vue实例 this._router = this.$options.router; //在vue实例上添加一个_router指向构造时的vue-router实例 this._router.init(this); //vue-router实例调用init()进行初始化,参数为vue实例 vue.util.definereactive(this, '_route', this._router.history.current); //通过vue的definereactive把_router变成响应式,等于this._router.history.current } else { //非根组件 this._routerroot = (this.$parent && this.$parent._routerroot) || this; //如果this.$options.router则设置$this._routerroot为占位符节点的_routerroot,这样就可以访问到vue-rooter实例了 } registerinstance(this, this); }, destroyed: function destroyed() { //销毁生命周期函数 registerinstance(this); } }); /*略*/ vue.component('routerview', view); //注册routerview组件 vue.component('routerlink', link); //注册routerlink逐渐 }
我们可以看到通过mixin混入在vue的beforecreate生命周期函数内插入了一段代码,会通过this.$options.router.init(this)执行初始化代码(this.$options.router就是我们执行new vue()时传入的vuerouter实例),这样就会执行vuerouter的init()方法了,另外还会执行vue.component()方法将routerview和routerlink组件注册为全局组件。
vuerouter的init方法就是初始化路由,如果当前页面没有路由(例如http://test.com/)则初始化为根地址/(例如http://test.com/#/),就是执行基类的transitionto方法进行跳转的过程,具体就不贴代码了,一贴就太多代码了。
vuerouter的执行过程
我们以上一篇文章https://www.cnblogs.com/greatdesert/p/12398443.html为例,依次整理一下vuerouter的执行过程
上面是加载的过程,对于例子里们我们执行new vuerouter的时候:
const routes = [ //定义路由指向 {path:'/login',component:login}, {path:'/hello',name:'user',component:hello}, {path:'/info/:id',component:info}, ] var router = new vuerouter({ //创建一个vuerouter实例 routes })
会执行vue-router的构造函数:
var vuerouter = function vuerouter (options) { //构造函数 if ( options === void 0 ) options = {}; //如果option为undefined,则修正为空对象 this.app = null; this.apps = []; this.options = options; this.beforehooks = []; this.resolvehooks = []; this.afterhooks = []; this.matcher = creatematcher(options.routes || [], this); //将路由信息转换为一个对象信息,返回一个对象,含有match和addroutes属性,分别对应两个函数 //初始化/修正mode var mode = options.mode || 'hash'; //如果没有传mode,则默认为hash模式 this.fallback = mode === 'history' && !supportspushstate && options.fallback !== false; //如果当前为history模式,但是浏览器不支持pushstate,则fallback不为false 则设置fallback为true if (this.fallback) { mode = 'hash'; } if (!inbrowser) { mode = 'abstract'; } this.mode = mode; switch (mode) { //根据不同的模式,对this.history做出实例化 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: { assert(false, ("invalid mode: " + mode)); } } };
creatematcher函数会解析我们传入的router值,该函数逻辑如下:
function creatematcher (routes,router) { var ref = createroutemap(routes); //创建一个map,就是上面第一步说的路由记录 var pathlist = ref.pathlist; var pathmap = ref.pathmap; var namemap = ref.namemap; function addroutes (routes) { createroutemap(routes, pathlist, pathmap, namemap); } function match (raw,currentroute,redirectedfrom) {/**/} function redirect (record,location) { /**/ } function alias (record,location,matchas) { /**/ } function _createroute (record,location,redirectedfrom) { /**/ } return {match: match,addroutes: addroutes} //返回这一个对象,我们可以通过直接执行这两个键对应的函数来匹配路由记录 }
对于例子里来说,执行到这里创建的路由记录如下:
namemap是给命名路由用的,pathlist是存储所有的路劲,pathmap才是所有路由记录的地方。
有了路由记录,vue-link和vue-view组件就可以大展手脚了,这两个组件后面再单独详解
如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复
Html+Css+Jquery实现左侧滑动拉伸导航菜单栏的示例代码
Html5 Canvas实现图片标记、缩放、移动和保存历史状态功能 (附转换公式)
html5 移动端视频video的android兼容(去除播放控件、全屏)
网友评论