plugins
Nuxt 会自动读取 app/plugins/ 目录中的文件,并在创建 Vue 应用时加载它们。
nuxt.config 中。.server 或 .client 后缀,以便仅在服务端或客户端加载插件。已注册的插件
只有目录顶层的文件(或任何子目录中的 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 会被注册。
若要添加子目录中的插件,可以使用 app/plugins 选项配置 nuxt.config.ts
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.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 插件中使用 组合式函数 以及 工具函数 (utils)
export default defineNuxtPlugin((nuxtApp) => {
const foo = useFoo()
})
不过,请记住,这存在一些限制和差异:
插件是按顺序调用的,且先于所有其他内容执行。你使用的组合式函数可能依赖于尚未被调用的插件。
通常情况下,Vue.js 组合式函数绑定到当前的组件实例,而插件仅绑定到
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 而非提供助手函数,以避免污染全局命名空间并保持主包入口文件精简。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 插件
如果你想使用 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
deno add -D npm: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 指令 (Directives)
同样,你也可以在插件中注册自定义 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 中提供一个“存根 (stub)”指令。