# 插件
插件是一个自包含的代码经常被用来为Vue添加一个全局级别的功能。它也是一个暴露`install()`方法或函数的`object`。
<br />
插件没有严格的范围定义,但通用场景插件的用途包括:
1. 加入一些全局的方法或属性,如`[vue-custom-element](https://github.com/karol-f/vue-custom-element)`。
2. 加入一个或多个全局资源:指令/过滤器/过渡效果等(如[vue-touch](https://github.com/vuejs/vue-touch))。
3. 通过全局mixin添加一些组件选项(如[vue-router(https://github.com/vuejs/vue-router)])。
4. 通过附加到`config.globalProperties`添加一些全局实例方法。
5. 提供API的类库,同时注入上面一些组合功能(如[vue-router(https://github.com/vuejs/vue-router)])。
<br />
## 编写组件
为了更好理解如何创建一个vue.js的插件,我们编写一个简单版本插件实现一个`i18n`准备好的字符串。
一旦这个插件被加入应用,如果是对象就会自动调用`install`方法,如果是一个函数,就会调用函数自己。两种情况都会接收两个参数 - Vue `createApp`生成的`app`对象结果,和用户传入的选项。
让我们开始配置这个插件。推荐在一个独立文件中创建和导出插件,你下方示例一样保持逻辑的包含与分隔:
~~~
// plugins/i18n.js
export default {
install: (app, options) => {
// 插件代码写在这里
}
}
~~~
我们想定义一个函数来翻译整个应用可用的键(keys),所以我们使用`app.configProperties`暴露出来。
函数会收到一个`key`字符串,它将会被用来查找用户提供选项的翻译字符串。
~~~
// plugins/i18n.js
export default {
install: (app, options) => {
app.config.globalProperties.$translate = key => {
return key.split('.').reduce((o, i) => {
if (o) return o[i]
}, options)
}
}
}
~~~
我们假设用户使用这个插件时会传递一个在选项中包含翻译键的对象参数。我们的`$translate`函数携带一个字符串比如`greetings.hello`,内部根据用户提供的配置返回翻译后的值 - 这个案例中是:`Bonjour!`:
~~~
greetings: {
hello: 'Bonjour!',
}
~~~
插件也允许我们使用注入(`inject`)为用户提供一个函数或属性。例如,我们可以让应用有权限访问`options`参数来使用translations对象。
~~~
// plugins/i18n.js
export default {
install: (app, options) => {
app.config.globalProperties.$translate = key => {
return key.split('.').reduce((o, i) => {
if (o) return o[i]
}, options)
}
app.provide('i18n', options)
}
}
~~~
现在插件用户可以在组件中使用`inject['i18in']`来访问对象。
另外因为我们有权限访问`app`对象,所有其他能力如`mixin`和`directive`也在插件中可用。学习更多`createApp`和应用实例知识,参考[应用API文档](https://v3.vuejs.org/api/application-api.html)。
~~~
// plugins/i18n.js
export default {
install: (app, options) => {
app.config.globalProperties.$translate = (key) => {
return key.split('.')
.reduce((o, i) => { if (o) return o[i] }, options)
}
app.provide('i18n', options)
app.directive('my-directive', {
mounted (el, binding, vnode, oldVnode) {
// 一些逻辑 ...
}
...
})
app.mixin({
created() {
// 一些逻辑...
}
...
})
}
}
~~~
<br />
## 使用插件
当应用通过`createApp`初始完成后,你就可以调用`use()`方法将插件添加到应用。
我们将使用前面章节创建的`i18inPlugin`插件作为使用的目标。
`use()`方法有两个参数,第一个是被安装的插件,这个例子中是`i18inPlugin`。
<br />
它同样会阻止你调用同一插件多次,所以不同时间多次调用同一插件只会安装一次。
第二个参数是可选的,依赖每个指定的插件。`i18inPlugin`示例中,是需要翻译的字符串。
>[info] 提示
> 如果你使用第三方插件如`Vuex`或`Vue router`,都是需要查看文档了解指定插件期望第二个参数传入什么。
~~~
import { createApp } from 'vue'
import Root from './App.vue'
import i18nPlugin from './plugins/i18n'
const app = createApp(Root)
const i18nStrings = {
greetings: {
hi: 'Hallo!'
}
}
app.use(i18nPlugin, i18nStrings)
app.mount('#app')
~~~
访问[awesome](https://github.com/vuejs/awesome-vue#components--libraries)查找大量社区贡献插件及类库。