plugins
Nuxt 会自动读取 plugins/ 目录中的文件,并在创建 Vue 应用程序时加载它们。
nuxt.config 中。.server 或 .client 后缀,以便仅在服务器端或客户端加载插件。| 插件类型 | 执行时机/频率 |
|---|---|
*.client.ts 插件 | ✅ 客户端 应用初始化时 执行一次 |
*.server.ts 插件 | ✅ 每次 SSR 请求时 执行一次 |
通用 .ts 插件 | ✅ 客户端执行一次 ✅ SSR 请求时每次执行 |
| 客户端操作 | 是否触发 SSR 请求 | 说明 |
|---|---|---|
| 地址栏访问 URL / 页面刷新 | ✅ 是 | 新请求 |
| 外部链接跳转进入 Nuxt 页面 | ✅ 是 | 新访问 |
<NuxtLink> 内部导航 | ❌ 否 | 客户端渲染 |
使用 router.push() 跳转 | ❌ 否 | 客户端渲染 |
| 预渲染的页面访问 | ❌ 否(读取静态) | 类似静态 HTML |
静态部署(如 nitro preset: static) | ❌ 否 | 不存在 SSR,只有 HTML |
/api/** 路由不会渲染页面,它只执行 server/api/*.ts 里的逻辑
但 Nuxt 插件仍会注入其执行上下文(nuxtApp)。可以通过路径判断来区别不同请求执行逻辑。已注册插件
只有目录顶层的文件(或任何子目录中的 index 文件)才会自动注册为插件。
-| plugins/
---| foo.ts // scanned
---| bar/
-----| baz.ts // not scanned
-----| foz.vue // not scanned
-----| index.ts // currently scanned but deprecated
只有 foo.ts 和 bar/index.ts 会被注册。
要在子目录中添加插件,您可以使用 nuxt.config.ts 中的 plugins 选项:
export default defineNuxtConfig({
plugins: [
'~/plugins/bar/baz',
'~/plugins/bar/foz'
]
})
创建插件
传递给插件的唯一参数是 nuxtApp。
export default defineNuxtPlugin(nuxtApp => {
// Doing something with nuxtApp
})
对象语法插件
也可以使用对象语法定义插件,以用于更高级的用例。例如:
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 会静态地预加载任何钩子监听器,允许您定义钩子而无需担心插件注册的顺序。注册顺序
您可以通过在文件名中添加 “字母” 编号前缀来控制插件的注册顺序。
plugins/
| - 01.backface-visibility.md.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) {
// the next plugin will be executed immediately
}
})
具有依赖项的插件
如果一个插件需要在另一个插件运行完毕后才能运行,您可以将该插件的名称添加到 dependsOn 数组中。
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
}
})
使用 Composables
您可以在 Nuxt 插件中使用 composables 以及 utils:
export default defineNuxtPlugin((nuxtApp) => {
const foo = useFoo()
})
但是,请记住存在一些限制和差异:
如果一个 composable 依赖于稍后注册的另一个插件,它可能无法正常工作。
插件按顺序依次调用,并且在所有其他操作之前调用。您可能会使用一个依赖于尚未调用的另一个插件的 composable。
如果一个 composable 依赖于 Vue.js 生命周期,它将无法正常工作。
通常,Vue.js composables 绑定到当前的组件实例,而插件仅绑定到 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">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>
<template>
<div>
{{ $hello('world') }}
</div>
</template>
请注意,我们强烈建议使用 composables 而不是提供助手函数,以避免污染全局命名空间并保持主 bundle 入口文件的小巧。
ref 或 computed,它在组件 <template> 中将不会被解包。这是由于 Vue 处理非模板顶层 ref 的方式所致。您可以在 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) => {
// 1. 初始化 Google Analytics,注入 $gtag 方法供全局调用
nuxtApp.vueApp.use(VueGtag, {
property: {
id: 'GA_MEASUREMENT_ID' // 替换为实际跟踪ID
}
})
// 2. 启用路由自动跟踪,自动监听 Vue Router 的路由变化,发送 page_view 事件到 GA
trackRouter(useRouter())
})
Vue 指令
类似地,您可以在插件中注册自定义 Vue 指令。
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 中为服务器提供一个“存根”指令。