概览
vue3
的生态圈提供了许多方便的插件或者工具,比如pinia
、vue-router
和Element Plus
等,使用插件的写法一般如下:
const app = createApp(App);
app.use(pinia);
app.use(router);
app.use(ElementPlus, { locale }); // 第二个参数:{locale} 为传给插件的参数
源码分析
vue3
中use
方法的实现
打印createApp
的返回值app
,如下图所示,
其实现如下:
use(plugin, ...options) {
if (installedPlugins.has(plugin)) {
warn2(`Plugin has already been applied to target app.`);
} else if (plugin && isFunction(plugin.install)) {
installedPlugins.add(plugin);
plugin.install(app, ...options);
} else if (isFunction(plugin)) {
installedPlugins.add(plugin);
plugin(app, ...options);
} else if (true) {
warn2(
`A plugin must either be a function or an object with an "install" function.`
);
}
return app;
},
实现的源码中,installedPlugins
是个WeakSet
类型的局部变量,先是判断插件plugin
是否被安装过,插件只需要安装一次,不能重复安装;然后判断插件是否存在install
方法,若存在就调用plugin.add
方法,并将console.log
打印出来的app
变量的值会作为参数传给plugin
;若plugin
不存在install
方法,且其自身就是个函数类型,就调用plugin(app)
,否则报错;最后返回app
。
vue3
中接收插件的就这段代码,可以说理解起来非常简单,基于此,就可以在插件plugin
中拿到app
这个实例对象了。
插件中的install
在 Pinia 部分源码浅析一文中有提到 Pinia
相关的实现
我们可以自己写个 Plugin
测试下,其本质上就是一个包含install
属性方法的一个对象而已。
如下:
const plugin = {
install: (app) => {
console.log("🚀 ~ app:", app);
},
};
export default plugin;
打印出来如下: