plugins
Nuxt 会自动读取 plugins/
目录中的文件,并在创建 Vue 应用时加载它们。
¥Nuxt automatically reads the files in the plugins/
directory and loads them at the creation of the Vue application.
nuxt.config
中。.server
或 .client
后缀,以便仅在服务器端或客户端加载插件。已注册插件
¥Registered Plugins
只有目录顶层的文件(或任何子目录中的索引文件)才会自动注册为插件。
¥Only files at the top level of the directory (or index files within any subdirectories) will be auto-registered as plugins.
-| plugins/
---| foo.ts // scanned
---| bar/
-----| baz.ts // not scanned
-----| foz.vue // not scanned
-----| index.ts // currently scanned but deprecated
只有 foo.ts
和 bar/index.ts
会被注册。
¥Only foo.ts
and bar/index.ts
would be registered.
要在子目录中添加插件,你可以在 nuxt.config.ts
中使用 plugins
选项:
¥To add plugins in subdirectories, you can use the plugins
option in nuxt.config.ts
:
export default defineNuxtConfig({
plugins: [
'~/plugins/bar/baz',
'~/plugins/bar/foz'
]
})
创建插件
¥Creating Plugins
传递给插件的唯一参数是 nuxtApp
。
¥The only argument passed to a plugin is nuxtApp
.
export default defineNuxtPlugin(nuxtApp => {
// Doing something with nuxtApp
})
对象语法插件
¥Object Syntax Plugins
对于更高级的用例,也可以使用对象语法定义插件。例如:
¥It is also possible to define a plugin using an object syntax, for more advanced use cases. For example:
export default defineNuxtPlugin({
name: 'my-plugin',
enforce: 'pre', // or 'post'
async setup (nuxtApp) {
// this is the equivalent of a normal functional plugin
},
hooks: {
// You can directly register Nuxt app runtime hooks here
'app:created'() {
const nuxtApp = useNuxtApp()
// do something in the hook
}
},
env: {
// Set this value to `false` if you don't want the plugin to run when rendering server-only or island components.
islands: true
}
})
enforce: import.meta.server ? 'pre' : 'post'
将使 Nuxt 将来为你的插件进行的任何优化失效。 Nuxt 在使用对象语法时会静态预加载所有钩子监听器,让你无需担心插件注册的顺序即可定义钩子。注册顺序
¥Registration Order
你可以通过在文件名前添加 'alphabetical' 编号来控制插件的注册顺序。
¥You can control the order in which plugins are registered by prefixing with 'alphabetical' numbering to the file names.
plugins/
| - 01.myPlugin.ts
| - 02.myOtherPlugin.ts
在此示例中,02.myOtherPlugin.ts
将能够访问由 01.myPlugin.ts
注入的任何内容。
¥In this example, 02.myOtherPlugin.ts
will be able to access anything that was injected by 01.myPlugin.ts
.
当你的插件依赖于另一个插件时,这很有用。
¥This is useful in situations where you have a plugin that depends on another plugin.
10.myPlugin.ts
会排在 2.myOtherPlugin.ts
之前。这就是为什么示例中在单个数字前加上 0
前缀的原因。加载策略
¥Loading Strategy
并行插件
¥Parallel Plugins
默认情况下,Nuxt 按顺序加载插件。你可以将插件定义为 parallel
,这样 Nuxt 就不会等到插件执行结束后才加载下一个插件。
¥By default, Nuxt loads plugins sequentially. You can define a plugin as parallel
so Nuxt won't wait until the end of the plugin's execution before loading the next plugin.
export default defineNuxtPlugin({
name: 'my-plugin',
parallel: true,
async setup (nuxtApp) {
// the next plugin will be executed immediately
}
})
依赖插件
¥Plugins With Dependencies
如果一个插件需要等待另一个插件运行,你可以将该插件的名称添加到 dependsOn
数组中。
¥If a plugin needs to wait for another plugin before it runs, you can add the plugin's name to the dependsOn
array.
export default defineNuxtPlugin({
name: 'depends-on-my-plugin',
dependsOn: ['my-plugin'],
async setup (nuxtApp) {
// this plugin will wait for the end of `my-plugin`'s execution before it runs
}
})
使用可组合组件
¥Using Composables
你可以在 Nuxt 插件中使用 composables 和 utils:
¥You can use composables as well as utils within Nuxt plugins:
export default defineNuxtPlugin((nuxtApp) => {
const foo = useFoo()
})
但是,请记住存在一些限制和差异:
¥However, keep in mind there are some limitations and differences:
插件按顺序调用,且优先于其他所有操作。你可以使用依赖于尚未调用的另一个插件的组合项。
通常,Vue.js 可组合项绑定到当前组件实例,而插件仅绑定到
nuxtApp
实例。提供帮助函数
¥Providing Helpers
如果你希望在 NuxtApp
实例上提供一个辅助函数,请将其从插件中以 provide
键返回。
¥If you would like to provide a helper on the NuxtApp
instance, return it from the plugin under a provide
key.
export default defineNuxtPlugin(() => {
return {
provide: {
hello: (msg: string) => `Hello ${msg}!`
}
}
})
export default defineNuxtPlugin({
name: 'hello',
setup () {
return {
provide: {
hello: (msg: string) => `Hello ${msg}!`
}
}
}
})
然后,你可以在组件中使用助手:
¥You can then use the helper in your components:
<script setup lang="ts">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>
<template>
<div>
{{ $hello('world') }}
</div>
</template>
composables
而不是提供辅助程序,以避免污染全局命名空间并保持主 bundle 条目较小。ref
或 computed
,它将不会被解包到组件 <template>
中。:br 这是由于 Vue 处理非模板顶层引用的方式所致。你可以在 在 Vue 文档中 上阅读更多相关信息。¥If your plugin provides a ref
or computed
, it will not be unwrapped in a component <template>
.This is due to how Vue works with refs that aren't top-level to the template. You can read more about it in the Vue documentation.
Typing 插件
¥Typing Plugins
如果你从插件返回辅助函数,它们将被自动输入;你会发现它们被输入到 useNuxtApp()
的返回值中,并且存在于你的模板中。
¥If you return your helpers from the plugin, they will be typed automatically; you'll find them typed for the return of useNuxtApp()
and within your templates.
useNuxtApp()
来获取类型版本。但一般来说,除非你确定插件的顺序,否则应避免这种情况。对于高级用例,你可以像这样声明注入属性的类型:
¥For advanced use-cases, you can declare the type of injected properties like this:
declare module '#app' {
interface NuxtApp {
$hello (msg: string): string
}
}
declare module 'vue' {
interface ComponentCustomProperties {
$hello (msg: string): string
}
}
export {}
@vue/runtime-core
,直到 this issue 问题得到解决。Vue 插件
¥Vue Plugins
如果你想使用 Vue 插件(例如 vue-gtag)来添加 Google Analytics(分析)标签,可以使用 Nuxt 插件来实现。
¥If you want to use Vue plugins, like vue-gtag to add Google Analytics tags, you can use a Nuxt plugin to do so.
首先,安装 Vue 插件依赖:
¥First, install the Vue plugin dependency:
npm install --save-dev vue-gtag-next
yarn add --dev vue-gtag-next
pnpm add -D vue-gtag-next
bun add -D vue-gtag-next
然后创建一个插件文件:
¥Then create a plugin file:
import VueGtag, { trackRouter } from 'vue-gtag-next'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(VueGtag, {
property: {
id: 'GA_MEASUREMENT_ID'
}
})
trackRouter(useRouter())
})
Vue 指令
¥Vue Directives
同样,你可以在插件中注册自定义 Vue 指令。
¥Similarly, you can register a custom Vue directive in a plugin.
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('focus', {
mounted (el) {
el.focus()
},
getSSRProps (binding, vnode) {
// you can provide SSR-specific props here
return {}
}
})
})
~/plugins/my-directive.client.ts
,并在 ~/plugins/my-directive.server.ts
中为服务器提供 'stub' 指令。¥If you register a Vue directive, you must register it on both client and server side unless you are only using it when rendering one side. If the directive only makes sense from a client side, you can always move it to ~/plugins/my-directive.client.ts
and provide a 'stub' directive for the server in ~/plugins/my-directive.server.ts
.