Vue 插件及 Vue.use 实现原理
# 前言
插件是自包含的代码,通常向 Vue 添加全局级功能。插件的功能范围没有严格的限制,一般有下面几种:
添加全局方法或者 property。
添加全局资源:指令/过渡等。
通过全局 mixin 来添加一些组件选项
添加全局实例方法,通过把它们添加到
config.globalProperties
上实现。一个库,提供自己的 API,同时提供上面提到的一个或多个功能。
# 使用插件
在使用 createApp()
初始化 Vue 应用程序后,我们可以通过调用 use()
方法将插件添加到应用程序中。比如:
import { createApp } from 'vue'
import Root from './App.vue'
import axios from 'axios'
import Router from 'vue-router'
import Vuex from 'vuex'
const app = createApp(Root)
// axios 没有提供 install 方法,无法使用 use 方法注册,可以通过挂载到 globalProperties 上,这样就可以在任意一个组件里通过 this.$http 访问到 axios API。
app.config.globalProperties.$http = axios
app.use(Router)
app.use(Vuex)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
use()
方法有两个参数:
- 第一个是要安装的插件,它还会自动阻止你多次使用同一插件,因此在同一插件上多次调用只会安装一次该插件。
- 第二个参数是可选的,并且取决于每个特定的插件。
# 插件注册原理
当插件被添加到应用程序中时,
如果它是一个对象,就会调用内置的
install
方法。如果它是一个 function,则函数本身将被调用。
在这两种情况下——它都会收到两个参数:由 Vue 的 createApp
生成的 app
对象和用户传入的选项。
如何理解上面这段话?直接看源码:https://github.com/vuejs/vue/blob/main/src/core/global-api/use.ts (opens new window)
import type { GlobalAPI } from 'types/global-api'
import { toArray, isFunction } from '../util/index'
export function initUse(Vue: GlobalAPI) {
// 定义 use 方法
Vue.use = function (plugin: Function | any) {
// 声明一个 installedPlugins 数组,用来存放安装过的插件
const installedPlugins = this._installedPlugins || (this._installedPlugins = [])
// 先检查有没有安装过,也就是在 installPlugins 数组中看能不能找到,如果能找到则表名已经安装过了,就直接返回 vue 实例,防止重复安装。
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// 通过 toArray 方法转化成数组,然后将 vue 实例放到数组的第一个位置,这是因为后续调用 install 方法都必须传入 vue 作为参数。
const args = toArray(arguments, 1)
args.unshift(this)
// 如果 plugin 对象的 install 是一个方法,那么就将参数传入并执行 install 方法,完成插件的安装。
if (isFunction(plugin.install)) {
plugin.install.apply(plugin, args)
} else if (isFunction(plugin)) {
// 如果 plugin 是一个方法,那么就把他当作是 install 方法来执行。
plugin.apply(null, args)
}
// 将 plugin 压入到 installedPlugin 数组中,表示插件已经安装,防止后续重复安装
installedPlugins.push(plugin)
// 返回 vue 实例
return this
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
这就是 use 的实现原理,是不是很简单。。。本质上就是执行了一个 install 方法,install 里的内容由开发者自己定义。
# 编写插件
将自己编写的组件,像 element-ui
一样使用 app.use()
方法来使用
首先自定义一个组件
example.vue
在同一目录下建立
index.js
文件, 在这个文件中使用install
方法来全局注册该组件
import Example from './example.vue'
export default {
install: (app, options) => {
app.component('Example-name', Example)
}
}
2
3
4
5
6
7
- 这样就可以通过 use 方法来全局注册该组件, 也可发布成 npm 包,给别人下载使用
# 最后
关于 Vue 插件 更详细的介绍,可以查看官网介绍:https://v3.cn.vuejs.org/guide/plugins.html (opens new window)
awesome-vue (opens new window) 集合了大量由社区贡献的插件和库