plugins
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
:
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: {
// Здесь вы можете напрямую зарегистрировать runtime-хуки приложения Nuxt
'app:created'() {
const nuxtApp = useNuxtApp()
// сделать что-то в хуке
}
},
env: {
// Установите это значение в `false`, если вы не хотите, чтобы плагин запускался при рендеринге только серверных или island-компонентов.
islands: true
}
})
Например, установка
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
.Стратегия загрузки
Параллельные плагины
By default, Nuxt loads plugins sequentially. You can define a plugin as parallel
so Nuxt won't wait until the end of the plugin's execution before loading the next plugin.
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` перед запуском
}
})
Использование композаблов
Вы можете использовать композаблы, а также утилиты в плагинах Nuxt:
export default defineNuxtPlugin((nuxtApp) => {
const foo = useFoo()
})
Однако имейте в виду, что существуют некоторые ограничения и различия:
Плагины вызываются последовательно и перед всем остальным. Вы можете использовать композабл, который зависит от другого плагина, который еще не был вызван.
Обычно композаблы Vue.js привязываются к текущему инстансу компонента, а плагины - только к инстансу
nuxtApp
.Предоставление хэлперов
Если вы хотите предоставить хэлпер для инстанса NuxtApp
, верните его из плагина под ключом provide
.
export default defineNuxtPlugin(() => {
return {
provide: {
hello: (msg: string) => `Привет ${msg}!`
}
}
})
Затем вы можете использовать этот хэлпер в своих компонентах:
<script setup lang="ts">
// альтернативно, вы также можете использовать его здесь
const { $hello } = useNuxtApp()
</script>
<template>
<div>
{{ $hello('world') }}
</div>
</template>
композаблы
вместо предоставления хэлперов, чтобы не загрязнять глобальное пространство имен и сохранить небольшой размер основного бандла.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
Затем создайте файл плагина:
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) {
// Здесь вы можете предоставить входные параметры, специфичные для SSR
return {}
}
})
})
~/plugins/my-directive.client.ts
и предоставить директиву 'заглушку' для сервера в ~/plugins/my-directive.server.ts
.