简单版本的VueRouter手写-插件的注册(有你不知道的小知识哦!)

432 阅读3分钟

vue-router

前言

哈哈哈哈,终于进入vue的学习环节了,我们先使用

vue create hello-world

创建一个模板,之后供我们使用

本次目标

做一个非常简单的手动路由 首先我们需要创建一个构造函数

export default class Router {}

很简单对不对,虽然这是我们的一小步,但是是我们的一大步啊!!!

接下来我们要思考一下我们该做什么了

3

2

1

揭晓答案:创建一个install 方法

为什么需要这个方法?

首先先送上Vue.js的官方文档开发插件

image.png Vue.use 方法会调用对应组件的 install 方法,所以我们需要对对应的方法进行一些声明

ps:有没有觉得有用的知识突然加一了??? 这还不加个关注?点赞?一键三连?

创建 install 方法

我们要定义一个静态方法,这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象,目前我们暂时用不到第二个参数,所以就先不考虑了

export default class Router {
  // Vue.use 方法会调用对应组件的 install 方法
  static install(Vue) {

  }
}

简单定义好了之后,我们需要去考虑一下一些问题,俗话说的好:磨刀不误砍柴工

整理一下install方法的目标

  • 判断插件是否被安装

    目的: 避免重复安装

  • install方法中的参数vue插入到全局中

    目的: 我们是在Router类的静态方法中获得的vue实例回调,但是我们在其他的实例方法中还需要调用到vue的实例,比如:router-linkrouter-view这两个组件都需要使用到这个方法,所以我们需要将vue保存到全局对象中

  • 将创建vue实例时候传入的Router对象注入到vue实例上

    目的::便于我们在页面中进行调用

判断插件是否被安装实现

这个就比较简单了,因为我们安装调用的是install静态方法,所以我们可以这样判断Router.install.installed

这里installed是我们的自定义属性,我们可以对他的值进行自定义,进行是否已经安装的判断。

代码如下:

export default class Router {
  // Vue.use 方法会调用对应组件的 install 方法
  static install(Vue) {
    // 1. 判断插件是否被安装
    if(Router.install.installed){
      return
    }
    Router.install.installed = true
  }
}

install方法中的参数vue插入到全局中

let _vue = null

export default class Router {
  // Vue.use 方法会调用对应组件的 install 方法
  static install(Vue) {
    ...
    // 2. 将`install`方法中的参数`vue`插入到全局中
    _vue = Vue
  }
}

将创建vue实例时候传入的Router对象注入到vue实例上

这一步比较的麻烦,首先我们要知道我们该怎么注入到vue实例上,而且我们需要区分是否是组件

先上代码:

 _vue.mixin({
      beforeCreate() {
        if(this.$options.router){
          _vue.prototype.$router = this.$options.router
        }
      }
    })

对,你没有看错!就是这个 mixin 方法,在 beforeCreat 生命周期里 Router 从当前 vue 实例的 options 中获得获得 router 对象并完成初始化操作。

  1. $options从哪里来呢?

    调用我们这个静态方法install的时候,我们的this指向了vue实例,所以我们就有了$options

  2. 为什么是在 $options 中调用 router 进行判断呢? 为什么?它到底放到 options 里做了什么?难道 vuejs 对自己官方提供的插件特殊提供了什么逻辑吗?(震惊🤯)

    官方文档,在查阅了文档之后,在vue-router使用中,我发现到了一些细节,如下图,我们可以看见,我们传递options 是这样进行操作的,也就是说 router 的启动交给了 vue 实例。所以就有了我们上面的代码

image.png

到这里我们的routerinstall函数简单版就构造好了