使用 Vue & UI Pro 的仪表板模板

插件

Nuxt 拥有一个插件系统,用于在创建 Vue 应用程序时使用 Vue 插件等。

Nuxt 会自动读取 plugins/ 目录中的文件,并在创建 Vue 应用程序时加载它们。

所有插件都会自动注册,您无需在 nuxt.config 中单独添加它们。
您可以在文件名中使用 .server.client 后缀,仅在服务器端或客户端加载插件。

已注册的插件

只有目录顶层的(或任何子目录中的索引文件)文件才会被自动注册为插件。

目录结构
-| plugins/
---| foo.ts      // scanned
---| bar/
-----| baz.ts    // not scanned
-----| foz.vue   // not scanned
-----| index.ts  // currently scanned but deprecated

只有 foo.tsbar/index.ts 会被注册。

要在子目录中添加插件,您可以使用 plugins 选项在 nuxt.config.ts 中。

nuxt.config.ts
export default 
defineNuxtConfig
({
plugins
: [
'~/plugins/bar/baz', '~/plugins/bar/foz' ] })

创建插件

传递给插件的唯一参数是 nuxtApp.

plugins/hello.ts
export default 
defineNuxtPlugin
(
nuxtApp
=> {
// Doing something with nuxtApp })

对象语法插件

也可以使用对象语法定义插件,用于更高级的用例。例如

plugins/hello.ts
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 能够对您的插件进行的任何未来优化。

注册顺序

您可以通过在文件名中添加“字母顺序”编号来控制插件注册的顺序。

目录结构
plugins/
 | - 01.myPlugin.ts
 | - 02.myOtherPlugin.ts

在这个例子中,02.myOtherPlugin.ts 将能够访问由 01.myPlugin.ts 注入的任何内容。

这在您有一个依赖于另一个插件的插件的情况下非常有用。

如果您不熟悉“字母顺序”编号,请记住文件名是作为字符串排序的,而不是作为数字值排序的。例如,10.myPlugin.ts 将排在 2.myOtherPlugin.ts 之前。这就是为什么示例在一位数前面添加 0 的原因。

加载策略

并行插件

默认情况下,Nuxt 按顺序加载插件。您可以将插件定义为 parallel,这样 Nuxt 不会在加载下一个插件之前等待插件执行结束。

plugins/my-plugin.ts
export default 
defineNuxtPlugin
({
name
: 'my-plugin',
parallel
: true,
async
setup
(
nuxtApp
) {
// the next plugin will be executed immediately } })

带有依赖关系的插件

如果一个插件需要在运行之前等待另一个插件,您可以将该插件的名称添加到 dependsOn 数组中。

plugins/depending-on-my-plugin.ts
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
  }
})

使用可组合函数

您可以在 Nuxt 插件中使用 composables 以及 utils

plugins/hello.ts
export default defineNuxtPlugin((nuxtApp) => {
  const foo = useFoo()
})

但是,请记住有一些限制和差异

如果一个可组合函数依赖于另一个稍后注册的插件,它可能无法正常工作。
插件按顺序调用,并且在其他任何内容之前调用。您可能会使用一个依赖于尚未调用的另一个插件的可组合函数。
如果一个可组合函数依赖于 Vue.js 生命周期,它将无法正常工作。
通常,Vue.js 可组合函数绑定到当前组件实例,而插件仅绑定到 nuxtApp 实例。

提供助手

如果您想在 NuxtApp 实例上提供一个助手,请在 provide 键下从插件中返回它。

export default 
defineNuxtPlugin
(() => {
return {
provide
: {
hello
: (
msg
: string) => `Hello ${
msg
}!`
} } })

然后您可以在组件中使用该助手

components/Hello.vue
<script setup lang="ts">
// alternatively, you can also use it here
const { $hello } = useNuxtApp()
</script>

<template>
  <div>
    {{ $hello('world') }}
  </div>
</template>
请注意,我们强烈建议使用 composables 而不是提供辅助函数来避免污染全局命名空间并保持主包入口文件的大小。
如果您的插件提供了 refcomputed,它将不会在组件 <template> 中被解包。
这是由于 Vue 如何处理模板中非顶层 ref 的工作原理。您可以在 Vue 文档 中了解更多相关信息。

类型插件

如果您从插件中返回辅助函数,它们将自动进行类型推断;您将在 useNuxtApp() 的返回值以及模板中找到它们的类型。

如果您需要在另一个插件中使用提供的辅助函数,您可以调用 useNuxtApp() 来获取类型化的版本。但一般来说,除非您确定插件的顺序,否则应该避免这样做。

对于高级用例,您可以像这样声明注入属性的类型

index.d.ts
declare module '#app' {
  interface NuxtApp {
    $hello (msg: string): string
  }
}

declare module 'vue' {
  interface ComponentCustomProperties {
    $hello (msg: string): string
  }
}

export {}
如果您使用的是 WebStorm,您可能需要增强 @vue/runtime-core,直到 此问题 被解决。

Vue 插件

如果您想使用 Vue 插件,例如 vue-gtag 来添加 Google Analytics 标签,您可以使用 Nuxt 插件来实现。

首先,安装 Vue 插件依赖项

yarn add --dev vue-gtag-next

然后创建一个插件文件

plugins/vue-gtag.client.ts
import VueGtag, { trackRouter } from 'vue-gtag-next'

export default defineNuxtPlugin((nuxtApp) => {
  nuxtApp.vueApp.use(VueGtag, {
    property: {
      id: 'GA_MEASUREMENT_ID'
    }
  })
  trackRouter(useRouter())
})

Vue 指令

类似地,您可以在插件中注册自定义 Vue 指令。

plugins/my-directive.ts
export default 
defineNuxtPlugin
((
nuxtApp
) => {
nuxtApp
.
vueApp
.
directive
('focus', {
mounted
(
el
) {
el
.focus()
},
getSSRProps
(
binding
,
vnode
) {
// you can provide SSR-specific props here return {} } }) })
如果您注册了 Vue 指令,您必须 在客户端和服务器端都注册它,除非您只在渲染其中一侧时使用它。如果指令只在客户端有意义,您始终可以将其移到 ~/plugins/my-directive.client.ts 并为服务器端提供一个“存根”指令,位于 ~/plugins/my-directive.server.ts 中。
Vue 文档中的自定义指令 中了解更多信息。