引文
在vue开发过程中,经常会用到Vue.use,例如Vue.use(ElementUI), Vue.use(VueRouter) 等等,遇到要封装一个公共组件或插件的需求,也会用到Vue.use去注册插件,那么use究竟做了什么,今天来探索下。
源码位置: vue\src\core\global-api\use.js
// toArray 将伪数组转为数组
export function toArray (list: any, start?: number): Array<any> {
start = start || 0
let i = list.length - start
const ret: Array<any> = new Array(i)
while (i--) {
ret[i] = list[i + start]
}
return ret
}
import { toArray } from '../util/index'
export function initUse (Vue: GlobalAPI) {
// 声明 Vue.use
Vue.use = function (plugin: Function | Object) {
// 已注册插件列表
const installedPlugins = (this._installedPlugins || (this._installedPlugins = []))
// 判断插件是否已注册 已注册返回
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// 附加参数处理
const args = toArray(arguments, 1)
// 附加参数添加this上下文
args.unshift(this)
// 判断有无install方法
if (typeof plugin.install === 'function') {
// 调用install方法
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
// 调用本身 指向null
plugin.apply(null, args)
}
// 插件列表添加
installedPlugins.push(plugin)
return this
}
}
综上所述,得出以下结论
- 在Vue.use的时候,参数接受方法或者对象,先判断插件是否已注册,已注册返回。
- 处理附加参数(
Vue.use(plugin, params1, .... ),获取到[params1, ....]),将this添加到参数首位 - 判断插件有无install方法,有的话执行插件install方法,没有的话执行插件本身
插件俩种形式对比
// main.js
import Vue from 'vue';
// 对象 含有install方法
const plugin1 = {
name: '萌新',
install(x) {
console.log('参数1', x);
console.log('参数2', [...arguments]);
console.log(this); // 对象 含有install方法源码 plugin.install.apply(plugin, args)
}
}
// 函数 没有install方法
const plugin2 = function(x) {
console.log('参数1', x);
console.log('参数2', [...arguments]);
console.log(this); // 函数 没有install方法源码 plugin.apply(null, args)
}
Vue.use(plugin1, '小菜菜', '菜鸡');
Vue.use(plugin2, '摸鱼', '大佬');
综上所述,可以得出以下结论
含有install方法的对象的this指向插件本身,所以可拓展性更高一些,function类型的插件this指向null,相对来说拓展性低一点。
总结
Vue.use()用来注册插件,接受函数或有install方法对象,首先会判断插件注册与否,已注册返回,未注册处理剩余参数,参数处理后判断插件是否含有install方法,有的话执行install方法this指向插件本身,没有则执行函数本身,this指向null。