下文记录了,自己第一天学习VueRouter的源码。VueRouter的源码有很多个组成部分,很大块,只能一天天的啃了,一下子肯定干不完。我的感受就是,短短的几行代码,但是里面的逻辑都很深。秋招加油叭!后面还会更新,如果有错误,请指正,轻喷!
// 原本的vue-router是怎么写的
// Vue注册使用VueRouter
Vue.use(VueRouter)
// 创建一个VueRouter实例
const router = new VueRouter({
routes: [
{
path: '/shouye',
component: homeComponent,
},
],
})
// 创建vue实例 注册router对象
new Vue({
router,
render: (h) => h(App),
}).$mount('#app')
// 模拟VueRouter部分
// 1. 声明一个全局变量_vue
// 为什么要声明要给全局变量_vue?
// 因为我们要在很多地方使用vue的构造函数,比如Vue.component来创建组件 -》生成 router-link 和 router-view组件
let _vue = null
// 2. 导出一个类
// 为什么要导出一个类
// 因为 new VueRouter()实例 就是把VueRouter当作一个构造函数或者是类来看待
export default class VueRouter {
// 3. 写install方法是为了什么?
// 这里对应Vue.use(VueRouter) Vue.use() 里面会接受一个“对象”或者“方法” 如果是方法 会直接调用 如果是对象 会调用这个对象里面的install方法 => 意味着如果是对象实例,里面必须有install方法 Vue才能够注册
// 调用的时候会传递 Vue构造函数
static install(Vue) {
// 4. 下面 为了判断 插件是否已经被安装,我们“手动”给VueRouter的install方法配上 install属性,方法也是对象 也可以配上属性,如果已经install了,就不需要再次install了,直接return
// 如果没有 我们才会去执行下面
if (VueRouter.install.installed) {
return
}
// 我们给这个属性 给为true 下次不会重复安装。
VueRouter.install.installed = true
// 给_vue全局变量 赋值 Vue这个构造函数
_vue = Vue
// 5. 这一步是混入,为什么考虑到用混入?
// 1. 因为我们想要进行下面这段代码,给Vue全局的构造函数的prototype原型对象挂载$router,这样挂载以后 在vue的任何实例、组件都可以使用this.$router.push this.$router.back……
// 2. 但是我们注意到 this这里指的是VueRouter 为什么? 因为是VueRouter.install()方法调用,
// 3. 所以我们考虑用Vue.mixin()方法 在Vue的构造函数里面的方法使用this,this就会指向Vue的构造函数
// 4. 为什么this要指向Vue构造函数的实例,因为 new Vue({router}) 里面的{router}是传递给 new Vue实例的,确切的来说指向的是每个vue实例
// _vue.prototype.$router = this.$options.router
_vue.mixin({
// 6. 我们希望每次都是new Vue实例的时候才挂载路由,new VueRouter实例而不是每次组件已创建,都会执行一遍,怎么操作呢?
// 1. 怎么判断是 new Vue 实例还是组件创建呢?
// 我们通过 beforeCreate()钩子函数,这个函数里面vue的实例已经创建好了 可以获取的到实例
// 我们判断是否有this.$options.router
// 就是看 new Vue({router}) 这个里面是否传递了router实例 如果传递了 就挂载到_vue.prototype.$router上面去
beforeCreate() {
if (this.$options.router) {
_vue.prototype.$router = this.$options.router
}
},
})
}
}