内容简介:使用过Vue的coder都知道,如果想注册一个vue的插件,在vue对象上能够使用的话(并不是绑在Vue.prototype上的那种暴力方式),必须使用Vue.use(你的插件)的方式来注册插件,Vue.use方法会寻找插件上的install方法,并且执行,如果插件没有install方法的话,就会报错,无法使用use来注册插件。 哦哟,是真的傲娇的一匹,所以想要使用VueRouter插件的话,就必须拥有一个install方法,所以我们来看看VueRouter的install方法都做了什么?
使用过Vue的coder都知道,如果想注册一个vue的插件,在vue对象上能够使用的话(并不是绑在Vue.prototype上的那种暴力方式),必须使用Vue.use(你的插件)的方式来注册插件,
用use注册插件需要注意什么呢?
Vue.use方法会寻找插件上的install方法,并且执行,如果插件没有install方法的话,就会报错,无法使用use来注册插件。 哦哟,是真的傲娇的一匹,所以想要使用VueRouter插件的话,就必须拥有一个install方法,
这么一看Vue的插件都需要install方法
所以我们来看看VueRouter的install方法都做了什么?
代码实在是不少,我是真的没办法一口气复制过来,截个图先给大家做一个展示吧
install 做了那几件事?
简单看来: Vue.mixin:侵入式的对每个Vue component进行了扩展
用ES5的defineProperty的方式设置$router
与
$route
属性。
创建了routerView 与RouterLink两个组件
对路由钩子进行一个统一设置(这块没看Vue.config.optionMergeStrategies)的源码,目前还不是很熟,当然这不重要了。先往下看
Vue-Router如何使用Vue的内容
大家都知道,Vue.mixin、Vue.component都是Vue类的方法,Vue-Router想要使用的话就必须引入Vue,这是毋庸置疑的,但是如果把Vue打包进入Vue-router的源码内,这必然导致Vue-router的包变得很大,
关键问题!!! 目前没有发现用Vue开发时哪个使用Vue-router开发不提前引入Vue的。
// 声明一个私有的_Vue用来接收外部的Vue类。 export let _Vue //install方法接收一个参数,也就是Vue类 export function install (Vue) { // 如果已经被注册了,并且 if (install.installed && _Vue === Vue) return install.installed = true //把Vue类赋值给私有_Vue _Vue = Vue 复制代码
这种方式只需要在install的时候使用全局的Vue类,并不需要将Vue打包进入Vue-router的源码内。
减少不必要的依赖,从我大Vue-router做起。
const isDef = v => v !== undefined //这是install方法中一个判断值是否为undefined的方法,在接下来会有很多次调用到它,请不要遗漏 复制代码
// 注册实例的方法 const registerInstance = (vm, callVal) => { //vm是什么?就是vue componet实例 let i = vm.$options._parentVnode // 这是一个类似链式调用的方式 // 目的是确保能确定到this.$options._parentVnode.data.registerRouteInstance是不是存在? // 如果找到了那么就自然而然的把i赋值为这个方法,然后执行它 if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) { i(vm, callVal) } } 复制代码
说到这里可能会很乱,我们先留下来这个内容,一会去看看哪里会调用它。
mixin 侵入了哪里?
Vue.mixin({ beforeCreate () { // 只有根节点的$options的属性中有router if (isDef(this.$options.router)) { this._routerRoot = this this._router = this.$options.router this._router.init(this) Vue.util.defineReactive(this, '_route', this._router.history.current) } else { this._routerRoot = (this.$parent && this.$parent._routerRoot) || this } registerInstance(this, this) }, destroyed () { registerInstance(this) } }) 复制代码
看到这里我们应该了解,Vue-Router在install的时候侵入了每个vue componet的beforeCreate以及destroyed生命周期钩子中,在创建之前以及摧毁的时候做一些事情。 做了什么呢? 我们好像看到了registerInstance方法。
// 接受了vue componet自己 registerInstance(this, this) 复制代码
这个时候重新看一下这个方法,意思就是寻找这个方法去调用一下,this.$options._parentVnode.data.registerRouteInstance(这个方法谁有呢?) 这个我也不知道,我就写在一个子组件内的方法,去查看一下它的父组件们族谱中谁有这个方法。
(function(t){ while(t){ if(typeof t.$options._parentVnode.data.registerRouteInstance === 'function'){ return t }else{ t = t.$parent } } return 'not find' })(t) 复制代码
各位看官这是一个很拙劣的方法(勿学)以后会优化这个方法的。 然后发现这个this是谁呢?就是在你使用vue-router时,那个我们对每个组件设置path的那个组件。可以看下面
new vueRouter({ xxx routes : [{ path : 'xxx', component : '某某组件' }] }) 复制代码
每个有这个方法的应该都是这里面设置过的组件,所有我就有一个猜测,是不是路由的改变会导致该路径跳转前后的组件进行生成与摧毁(展示与隐藏)在这些组件创建之前会调用registerInstance方法(这个方法我还没看内部实现)。以后会去验证这个猜测的准确程度。
终于知道这个registerInstance什么时候执行了
router这个属性谁有啊????
//this.$options.router是绑定在app根节点的组件上。所有只有根组件有这个router属性 //所以所有的vue component的_routerRoot、_router、都是一样的。 // this.$options.router存在吗?==》 是不是已经绑定万_routerRoot的根节点 if (isDef(this.$options.router)) { // 根节点的_routerRoot就是根节点的vue component this._routerRoot = this // vue router实例 this._router = this.$options.router // 执行init this._router.init(this) Vue.util.defineReactive(this, '_route', this._router.history.current) } else { // 如果没有这个属性 ==》 两种情况 还没绑定这个属性的根节点、不是根节点 // 未绑定属性的根节点组件,(根节点组件怎么会有爸爸呢)它不存在$parent属性、所以还是指向了自己 // 不是根节点组件,那就找它爸爸的_routerRoot属性,用它爸爸的 // vue的子组件beforeCreate肯定晚于父组件beforeCreate所以 // 所有的组件就像一棵组件树以一样大家,从根向所有树枝树杈去传递这个属性 // 大家都是用一个属性所以每个组件的_routerRoot都是根节点组件 this._routerRoot = (this.$parent && this.$parent._routerRoot) || this } registerInstance(this, this) 复制代码
所以大家可以尝试的在vue项目中打印出组件本身,查看_routerRoot属性时,每个组件的uid都是一样的,$el也是根节点标签的id 。这不实锤了!!
总结一下
我们可以看出来在vueRouter在注册方面有哪些重要的事?
-
1:并没有将Vue打包进入Vue-router插件,而是使用外部Vue引入的方式。
-
2: mixin侵入式的给每个Vue组件的beforeCreate与destroyed生命周期对组件指定路由组件进行了创建与摧毁。
-
3:所有Vue组件的_router都是同一个Vue-router实例,总之大家都是用一个的。
install方法就介绍到这里,下一节会开始讲述Vue-router的主构造函数。前端er,下一期不见不散
我是一个应届生,最近和朋友们维护了一个公众号,内容是我们在从应届生过渡到开发这一路所踩过的坑,已经我们一步步学习的记录,如果感兴趣的朋友可以关注一下,一同加油~
以上所述就是小编给大家介绍的《Vue-Router源码学习之install方法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 【MyBatis源码分析】insert方法、update方法、delete方法处理流程(上篇)
- 【MyBatis源码分析】insert方法、update方法、delete方法处理流程(上篇)
- Runtime源码 方法调用的过程
- Vue源码分析系列二:$mount()方法
- invalidate方法知多少[-View-] 源码级
- SpringBoot源码解析之main方法推断
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
游戏运营:高手进阶之路
饭大官人 / 电子工业出版社 / 2018-1-1 / 79.00元
《游戏运营:高手进阶之路》是一本系统的、成体系的、注重运营效能、强化系统思维、提升专业认知的书籍。《游戏运营:高手进阶之路》几乎完整覆盖了一个游戏运营人员日常工作中的方方面面,并从工作中具体的业务场景出发,归纳整理出各种解决问题的方法论。《游戏运营:高手进阶之路》为广大游戏从业者建立了完整的知识技能成长体系,包含两大岗位基本功—内容输出和协作推进,四大职业技能—活动策划、版本管理、用户运营、数据分......一起来看看 《游戏运营:高手进阶之路》 这本书的介绍吧!