Vue.use的工作原理(流程及部分源码)

218 阅读2分钟

这是我参与8月更文挑战的第22天,活动详情查看:         8月更文挑战 ​

序言

今天我们老大给我么将了一下Vue.use的工作原理,一开始他以为我们都会,没想到一圈下来竟然都不尽如意,原来表面看起来很熟悉的东西,认真总结,却发现遗漏的东西很多,并不连通,今天我们就来整理一下Vue.use的工作原理吧。

基本使用

在探寻工作原理之前,我们先来看下官方是如何定义我们使用的

  1. 添加全局方法或者 property。如:vue-custom-element
Vue.myGlobalMethod = function () {
    // 逻辑...
  }
  1. 添加全局资源:指令/过滤器/过渡等。如 vue-touch
Vue.directive('my-directive', {
    bind (el, binding, vnode, oldVnode) {
      // 逻辑...
    }
    ...
  })
  1. 通过全局混入来添加一些组件选项。如 vue-router
Vue.mixin({
    created: function () {
      // 逻辑...
    }
    ...
  })
  1. 添加 Vue 实例方法,通过把它们添加到 Vue.prototype 上实现。
Vue.prototype.$myMethod = function (methodOptions) {
    // 逻辑...
  }
  1. 一个库,提供自己的 API,同时提供上面提到的一个或多个功能。如 vue-router

Vue中的插件

看完了使用方法,我们看见,我们把要注册的插件引用作为参数传入,就能实现注册,那么我们的插件是如何完成注册的呢。 在这之前,我们看一下符合注册规则的插件长啥样。

  1. 插件的本质是一个函数或者是对象
  2. 如果是对象的话,里面要有一个install方法,为什么要Install方法呢,耐心看到执行流程你就会明白。

一个插件的例子

//为对象时
export default{
  objectPlugin
}
function install (Vue, option){
  console.log(vue);
  console.log(option);
  Vue.prototype.coolFish = coolFish
}
function coolFish (food){
  console.log(`coolFish like ${food}`)
}
//为function时
function funcPlugin(a,b){
  console.log('Plugin2 第一个参数:',a)
  console.log('Plugin2 第二个参数:',b)
}

我们通过分析上面代码,知道当插件为对象时, 有一个install 方法接受一个 Vue 实例和一个参数option,执行的操作为把当前的方法挂载到原型上面。当插件为function时,一切看起来很正常,我们接下来看一下Vue.use的源码,来理解一下为什么会这么做。

Vue.use源码分析

import { toArray } from '../util/index'export function initUse (Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }
​
    // additional parameters
    const args = toArray(arguments, 1)
    args.unshift(this)
    if (typeof plugin.install === 'function') {
      plugin.install.apply(plugin, args)
    } else if (typeof plugin === 'function') {
      plugin.apply(null, args)
    }
    installedPlugins.push(plugin)
    return this
  }
}

上面这段是Vue.use的源码片段,可以分为一下几个步骤

  1. 创建一个插件数组,并且检测传入插件是否已经在此数组中,如果有的话,就不注册,直接返回,以免插件重复注册。
  2. 将 options 类数组对象转换为数组,再将 Vue 实例插入,做第一项。
  3. 判断当前插件是否有 install 方法,有的话将参数使用apply传入,这样我们前面定义的install 方法就取到了 Vue 实例,完成原型挂载。
  4. 如果插件本身为一个函数,那么直接把当前参数绑定上去。
  5. 最后把绑定完成的方法,加入到注册列表,防止重复注册。

总结: 这样就解释了为啥当插件为对象时,需要 install 方法,这样才能把他绑定到原型上,完成动态注册。