Vue.use插件机制

在使用Vue开发应用程序的时候,我们经常使用第三方插件库来方便我们开发,例如:Vue-RouterVuexelement-ui等等。

// main.js
import Vue from 'vue'
import Router from 'vue-router'
import Vuex from 'vuex'
import ElementUI from 'element-ui'

Vue.use(Router)
Vue.use(Vuex)
Vue.use(ElementUI)

new Vue({})

new Vue之前,我们使用Vue.use方法来注册这些插件。其中,Vue.use作为一个全局方法,它是在initGlobalAPI方法内部通过调用initUse来注册这个全局方法的。

import { initUse } from './use'
export function initGlobalAPI (Vue: GlobalAPI) {
  // ...省略代码
  initUse(Vue)
  // ...省略代码
}

initUse方法的代码并不复杂,如下:

import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
  Vue.use = function (plugin: Function | Object) {
    // 1.检测是否已经注册了插件
    const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
    if (installedPlugins.indexOf(plugin) > -1) {
      return this
    }

   // 2.处理参数
    const args = toArray(arguments, 1)
    args.unshift(this)

    // 3.调用install方法
    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时,它只要做三件事情:检查插件是否重复注册处理插件参数调用插件的install方法

代码分析:

  • 检查插件是否重复注册:首先通过判断大Vue上的_installedPlugins属性是否已经存在当前插件,如果已经存在则直接返回;如果不存在才会执行后面的逻辑,假如我们有如下案例:
import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)
Vue.use(Router)

多次调用Vue.use()方法注册同一个组件,只有第一个生效。

  • 处理插件参数:有些插件在注册的时候,可能需要我们额外的传递一些参数,例如element-ui
import Vue from 'vue'
import ElementUI from 'element-ui'
Vue.use(ElementUI, { 
  size: 'small',
  zIndex: 3000
})

按照上面的例子,Vue.use()方法的arguments数组的第一项为我们传递的插件,剩下的参数才是我们需要的,因此通过toArray方法把arguments类数组转成一个真正的数组。注意,此时args变量不包含插件这个元素,随后再把当前this也就是大Vue也传递进数组中。

// 演示使用,实际为大Vue的构造函数
const args = ['Vue', { size: 'small', zIndex: 3000}]
  • 调用插件的install方法:从官网插件open in new window我们知道,如果我们在开发一个Vue插件,必须为这个插件提供一个install方法,当调用Vue.use()方法的时候会自动调用此插件的install方法,并把第二步处理好的参数传递进去。假如,我们有如下插件代码:
// plugins.js
const plugin = {
  install (Vue, options) {
    console.log(options) // {msg: 'test use plugin'}

    // 其它逻辑
  }
}


// main.js
import Vue from 'vue'
import MyPlugin from './plugins.js'
Vue.use(MyPlugin, { msg: 'test use plugin' })

install方法中,我们成功获取到了大Vue构造函数以及我们传递的参数,在随后我们就可以做一些其它事情,例如:注册公共组件、注册指令、添加公共方法以及全局Mixin混入等等。

最后更新时间:
贡献者: wangtunan