Vue.use( plugin )
- 参数
{Object | Function} plugin
安装 Vue.js 插件。如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。
该方法需要在调用 new Vue() 之前被调用。
当 install 方法被同一个插件多次调用,插件将只会被安装一次。
// 源码路径:src/core/global-api/use.js
/* @flow */
/*
toArray:将类数组对象转换为真正的数组。
*/
import { toArray } from "../util/index";
export function initUse(Vue: GlobalAPI) {
Vue.use = function (plugin: Function | Object) {
// 拿到已安装的插件或等于一个空数组
const installedPlugins =
this._installedPlugins || (this._installedPlugins = []);
/*
判断 plugin 是否已经存在
这也就是为什么插件多次调用只会被安装一次
*/
if (installedPlugins.indexOf(plugin) > -1) {
return this;
}
/*
additional parameters 附加参数
arguments 是一个类数组对象: Object { 0: 1, 1: 2, 2: 3, length:3 } <- 长这样
经过 toArray 转换会变成一个真正的数组(toArray方法可以看下面)
*/
const args = toArray(arguments, 1);
// 向数组头部添加this,保证函数的第一个参数是Vue
args.unshift(this);
// 判断 plugin 要么提供一个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;
};
}
toArray()
/**
* Convert an Array-like object to a real Array.
*
* 将类数组对象转换为真正的数组。
*/
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;
}
// 扩展:es6 更简单
示例
// 本身是一个函数
const plugin1 = (Vue) => {
Vue.prototype.Element = "饿了么ui";
};
// 本身是一个对象,需要提供一个install方法才会生效
const plugin2 = {
install: (Vue) => {
Vue.prototype.elementPlus = "elementPlus";
},
};
// 多次调用,插件将只会被安装一次。
Vue.use(plugin1);
Vue.use(plugin1);
Vue.use(plugin1);
Vue.use(plugin2);
const app = new Vue({
data() {
return {
count: 0,
};
},
}).$mount("#app");
总结
Vue.use会优先拿到已安装的插件,如果没有会直接等于一个空数组,然后再判断该插件是否已被注册,来防止重复注册,然后会将arguments类数组对象转换成一个真正的数组并且向头部添加Vue,最后就是判断插件要么本身是一个函数要么是一个对象并且提供install方法