很多使用Vue开发的童鞋,可能对Vue的原型对象prototype有了解过,但对于Vue.use只知如何使用,却不知其背后的含义。那么,今天我们就来瞧一瞧Vue.use()背后的逻辑。
官方对 Vue.use() 方法的说明:通过全局方法 Vue.use() 使用插件,Vue.use 会自动阻止多次注册相同插件,它需要在你调用 new Vue() 启动应用之前完成,Vue.use() 方法至少传入一个参数,该参数类型必须是 Object 或 Function。
如果是 Object,那么这个 Object 需要定义一个 install 方法;如果是 Function,那么这个函数就被当做 install 方法。在 Vue.use() 执行时 install 会默认执行,当 install 执行时第一个参数就是Vue,其他参数是 Vue.use() 执行时传入的其他参数。就是说使用它之后调用的是该组件的install 方法。
当 install 方法被同一个插件多次调用,插件将只会被安装一次。也就是说Vue.use 会自动阻止多次注册相同插件
示例
// 引入公共方法扩展
import common from '@/prototypeEx/common.js'
Vue.prototype.common = common
// 引入公共缓存方法
import cacheEx from '@/prototypeEx/cacheEx.js'
Vue.prototype.cacheEx = cacheEx
// 引入大数据展示 插件
const echarts = require('echarts')
Vue.prototype.$echarts = echarts
import uploader from 'vue-simple-uploader'
Vue.use(uploader)
// 引入自己封装的全局注册的公共组件
import ztable from '@/components/index.js'
Vue.use(ztable)
Vue.use和Vue.prototype没有本质区别,Vue.use就是在Vue.prototype基础上又封装了一层而已,他们实现的原理都是在Vue.prototype上添加了一个方法,Vue.prototype适合于注册Vue生态外的插件,也就是说不是为了Vue编写的插件,用Vue.prototype导入。Vue.use适合于注册Vue生态内的插件,也就是说针对Vue编写的插件用Vue.use导入。Vue.use和Vue.prototype最终的用途是一样的——都是为了能在全局引用。
分析过程
$echarts变量前加上$,是一种规范,是为了防止被组件中的变量意外覆盖,即防止命名冲突。
vue.prototype:实例上挂载属性/方法
在多个地方都需要使用但不想污染全局作用域的情况下,这样定义,在每个 Vue 实例中都可用。$ 表示这是一个在 Vue 所有实例中都可用的属性,常用于方法、变量等
每一个vue组件都是Vue的实例,所以组件内this可以拿到Vue.prototype上添加的属性和方法。
vue.use源码
Vue.use = function (plugin) {
if (plugin.installed) {
return;
}
// additional parameters
var args = toArray(arguments, 1);
args.unshift(this);
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args);
} else {
plugin.apply(null, args);
}
plugin.installed = true;
return this;
};
// 再来看一下一个插件的install方法内容, 我们居然看到了Vue.prototype.$toast = toast;,
// 准备好 install 方法 给 Vue.use() 使用
const install = function (Vue) {
if (install.installed) return;
install.installed = true;
// 将包装好的 toast 挂到Vue的原型上,作为 Vue 实例上的方法
Vue.prototype.$toast = toast;
}
看了源码才知道原来`Vue.use`主要是执行`install`方法,而`install`主要也是执行`Vue.prototype`方法。所以,其实`Vue.use()`方法的核心就是`Vue.prototype`,只不过又封装了一层,更加的灵活,扩展性更好。
把vue理解成一棵树,`Vue.use`和`Vue.prototype`都是在这颗树上挂载插件的方式,不同之处是使用`vue.prototype`,插件不需要实现`install`方法,简单粗暴,拿来就用,但是灵活性不如`Vue.use()`, 而`Vue.use()`,却要求插件必须实现`instal`方法(也就是说必须具有install方法的插件才能使用Vue.use(参数)注册,传入参数的插件是一个object,反之,使用Vue.use(参数)注册的插件,如果参数是对象,必须具有install方法)或者该插件本身就是函数(那么这个函数就被当做 install 方法),在`install`方法可以完成自己的逻辑, 所以`Vue.use()`的方式更加的强大,灵活,扩展性更好。
但是两者并没有高低之分, 只是有着各自的应用场景,`Vue.prototype`适合于非Vue生态的插件,而`Vue.use()`适合于Vue生态内的插件,一个简单实用,一个灵活扩展性好。而且,`Vue.use`的实现依赖于`Vue.prototype`,最本质的理解就是`Vue.use`包裹着`Vue.prototype`又进一步的封装了一次。
参考:Vue.use()的用法详解