Изучите Nuxt с коллекцией из 100+ советов!

plugins

Nuxt имеет систему плагинов, позволяющую использовать плагины Vue и многое другое при создании вашего Vue-приложения.

Nuxt автоматически считывает файлы из директории plugins/ и загружает их при создании приложения Vue.

Все плагины внутри автоматически регистрируются, вам не нужно отдельно добавлять их в nuxt.config.
Вы можете использовать суффикс .server или .client в имени файла, чтобы загрузить плагин только на сервере или клиента.

Зарегистрированные плагины

Только файлы на верхнем уровне директории (или индексные файлы в любых поддиректориях) будут автоматически зарегистрированы как плагины.

Структура директории
-| plugins/
---| foo.ts      // отсканировано
---| bar/
-----| baz.ts    // не сканируется
-----| foz.vue   // не сканируется
-----| index.ts  // в настоящее время сканируется, но устарел

Будут зарегистрированы только foo.ts и bar/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
=> {
// Делаем что-то с nuxtApp })

Плагины в объектном синтаксисе

Также, для более сложных случаев использования, можно определить плагин, используя синтаксис объекта. Например:

plugins/hello.ts
export default 
defineNuxtPlugin
({
name
: 'my-plugin',
enforce
: 'pre', // или 'post'
async
setup
(
nuxtApp
) {
// это эквивалент обычного функционального плагина },
hooks
: {
// Здесь вы можете напрямую зарегистрировать runtime-хуки приложения Nuxt 'app:created'() { const
nuxtApp
=
useNuxtApp
()
// сделать что-то в хуке } },
env
: {
// Установите это значение в `false`, если вы не хотите, чтобы плагин запускался при рендеринге только серверных или island-компонентов.
islands
: true
} })
Посмотрите видео от Александра Лихтера об объектном синтаксисе для плагинов Nuxt.
Если вы используете объектный синтаксис, свойства анализируются статически, чтобы создать более оптимизированную сборку. Поэтому не следует определять их во время рантайма.
Например, установка enforce: import.meta.server ? 'pre' : 'post' приведет к невозможности дальнейшей оптимизации, которую Nuxt сможет выполнить для ваших плагинов. При использовании объектного синтаксиса, Nuxt статически предварительно загружает все слушатели хуков, позволяя вам определять хуки, не заботясь о порядке регистрации плагинов.

Порядок регистрации

Вы можете контролировать порядок регистрации плагинов, добавляя к именам файлов префикс с 'алфавитной'(alphabetical) нумерацией.

Структура директории
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
) {
// следующий плагин будет выполнен немедленно } })

Плагины с зависимостями

Если плагину необходимо дождаться запуска другого плагина, вы можете добавить его имя в массив dependsOn.

plugins/depending-on-my-plugin.ts
export default defineNuxtPlugin({
  name: 'depends-on-my-plugin',
  dependsOn: ['my-plugin'],
  async setup (nuxtApp) {
    // этот плагин будет ждать окончания выполнения `my-plugin` перед запуском
  }
})

Использование композаблов

Вы можете использовать композаблы, а также утилиты в плагинах Nuxt:

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) => `Привет ${
msg
}!`
} } })

Затем вы можете использовать этот хэлпер в своих компонентах:

components/Hello.vue
<script setup lang="ts">
// альтернативно, вы также можете использовать его здесь
const { $hello } = useNuxtApp()
</script>

<template>
  <div>
    {{ $hello('world') }}
  </div>
</template>
Обратите внимание, что мы настоятельно рекомендуем использовать композаблы вместо предоставления хэлперов, чтобы не загрязнять глобальное пространство имен и сохранить небольшой размер основного бандла.
Если ваш плагин предоставляет ref или computed, он не будет развернут в <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:

npm install --save-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
) {
// Здесь вы можете предоставить входные параметры, специфичные для SSR return {} } }) })
Если вы регистрируете директиву Vue, вы должны зарегистрировать ее как на стороне клиента, так и на стороне сервера, если вы не используете ее при рендеринге только на одной стороне. Если директива имеет смысл только на клиенте, вы всегда можете переместить ее в ~/plugins/my-directive.client.ts и предоставить директиву 'заглушку' для сервера в ~/plugins/my-directive.server.ts.
Узнать больше Пользовательские директивы в документации Vue.