plugins
Nuxt 会自动读取 app/plugins/
目录中的文件,并在创建 Vue 应用程序时加载它们。
nuxt.config
中单独添加它们。.server
或 .client
后缀,以便仅在服务器或客户端加载特定的插件。注册的插件
只有目录顶层的文件(或任何子目录中的索引文件)才会被自动注册为插件。
-| plugins/
---| foo.ts // 被扫描
---| bar/
-----| baz.ts // 未被扫描
-----| foz.vue // 未被扫描
-----| index.ts // 当前被扫描但已弃用
只有 foo.ts
和 bar/index.ts
会被注册。
要在子目录中添加插件,您可以在 nuxt.config.ts
中使用 app/plugins
选项:
export default defineNuxtConfig({
plugins: [
'~/plugins/bar/baz',
'~/plugins/bar/foz'
]
})
创建插件
传递给插件的唯一参数是 nuxtApp
。
export default defineNuxtPlugin(nuxtApp => {
// 使用 nuxtApp 进行某些操作
})
对象语法插件
也可以使用对象语法定义插件,以适应更高级的用例。例如:
export default defineNuxtPlugin({
name: 'my-plugin',
enforce: 'pre', // 或 'post'
async setup (nuxtApp) {
// 这相当于一个普通功能插件
},
hooks: {
// 您可以在这里直接注册 Nuxt 应用运行时钩子
'app:created'() {
const nuxtApp = useNuxtApp()
// 在钩子中执行某些操作
}
},
env: {
// 如果您不希望插件在渲染仅服务器或岛屿组件时运行,请将此值设置为 `false`。
islands: true
}
})
例如,将
enforce: import.meta.server ? 'pre' : 'post'
设置为会妨碍 Nuxt 对您的插件进行任何未来优化。
Nuxt 会静态预加载使用对象语法时的任何钩子监听器,允许您定义钩子而无需担心插件注册的顺序。注册顺序
您可以通过在文件名之前添加“字母数字”编号来控制插件的注册顺序。
plugins/
| - 01.myPlugin.ts
| - 02.myOtherPlugin.ts
在此示例中,02.myOtherPlugin.ts
将能够访问 01.myPlugin.ts
所注入的任何内容。
这在您有一个依赖于另一个插件的插件的情况下是有用的。
10.myPlugin.ts
会出现在 2.myOtherPlugin.ts
之前。这就是示例中单个数字前缀为 0
的原因。加载策略
并行插件
默认情况下,Nuxt 按顺序加载插件。您可以将插件定义为 parallel
,以便 Nuxt 不会在加载下一个插件之前等待插件执行完毕。
export default defineNuxtPlugin({
name: 'my-plugin',
parallel: true,
async setup (nuxtApp) {
// 下一个插件将立即执行
}
})
有依赖的插件
如果一个插件需要等待另一个插件运行后再执行,您可以将插件的名称添加到 dependsOn
数组中。
export default defineNuxtPlugin({
name: 'depends-on-my-plugin',
dependsOn: ['my-plugin'],
async setup (nuxtApp) {
// 此插件将在 `my-plugin` 执行结束后再运行
}
})
使用组合式 API
您可以在 Nuxt 插件中使用 组合式 API 以及 工具函数:
export default defineNuxtPlugin((nuxtApp) => {
const foo = useFoo()
})
但是,请记住,存在一些限制和差异:
插件按顺序依次调用,并且在其他所有内容之前调用。您可能使用一个依赖于尚未调用的其他插件的组合式 API。
通常,Vue.js 组合式 API 绑定到当前组件实例,而插件仅绑定到
nuxtApp
实例。提供助手函数
如果您希望在 NuxtApp
实例上提供一个助手函数,请在插件中以 provide
键返回它。
export default defineNuxtPlugin(() => {
return {
provide: {
hello: (msg: string) => `Hello ${msg}!`
}
}
})
export default defineNuxtPlugin({
name: 'hello',
setup () {
return {
provide: {
hello: (msg: string) => `Hello ${msg}!`
}
}
}
})
然后您可以在组件中使用助手函数:
<script setup lang="ts">
// 另外,您也可以在这里使用
const { $hello } = useNuxtApp()
</script>
<template>
<div>
{{ $hello('world') }}
</div>
</template>
composables
而不是提供助手函数,以避免污染全局命名空间并保持主包入口小。ref
或 computed
,它将在组件 <template>
中不会被解包。这是因为 Vue 对于不在模板顶部的 refs 的处理方式。您可以在 Vue 文档 中了解更多相关信息。
插件类型定义
如果您从插件返回助手函数,助手函数将会被自动类型化;您会在 useNuxtApp()
的返回值以及您的模板中找到它们的类型。
useNuxtApp()
来获取类型化版本。但一般情况下,除非您确定插件的顺序,否则应避免这样做。对于高级用例,您可以如下声明注入属性的类型:
declare module '#app' {
interface NuxtApp {
$hello (msg: string): string
}
}
declare module 'vue' {
interface ComponentCustomProperties {
$hello (msg: string): string
}
}
export {}
@vue/runtime-core
,直到 此问题 得到解决。Vue 插件
如果您想使用 Vue 插件,例如 vue-gtag 来添加 Google Analytics 标签,您可以使用 Nuxt 插件来实现。
首先,安装 Vue 插件依赖项:
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
然后创建一个插件文件:
import VueGtag, { trackRouter } from 'vue-gtag-next'
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.use(VueGtag, {
property: {
id: 'GA_MEASUREMENT_ID'
}
})
trackRouter(useRouter())
})
Vue 指令
同样,您可以在插件中注册自定义 Vue 指令。
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.directive('focus', {
mounted (el) {
el.focus()
},
getSSRProps (binding, vnode) {
// 可在此提供服务器端渲染的特定属性
return {}
}
})
})
~/plugins/my-directive.client.ts
,并在 ~/plugins/my-directive.server.ts
中提供“存根”指令。