Nuxt Nation conference is coming. Join us on November 12-13.

Transitions

Применяйте переходы между страницами и лейаутами с помощью Vue или нативных View Transitions браузера.
Nuxt использует компонент Vue <Transition> для применения переходов между страницами и лейаутами.

Переходы между страницами

Вы можете включить переходы между страницами, чтобы применить автоматический переход для всех ваших страниц.

nuxt.config.ts
export default 
defineNuxtConfig
({
app
: {
pageTransition
: {
name
: 'page',
mode
: 'out-in' }
}, })
Если вы меняете лейауты, а также страницу, переход страницы, который вы здесь задали, не будет запущен. Вместо этого следует задать переход лейаута.

Чтобы начать добавлять переходы между страницами, добавьте следующий CSS в ваш app.vue:

<template>
  <NuxtPage />
</template>

<style>
.page-enter-active,
.page-leave-active {
  transition: all 0.4s;
}
.page-enter-from,
.page-leave-to {
  opacity: 0;
  filter: blur(1rem);
}
</style>

Это дает следующий результат при навигации между страницами:

Чтобы задать другой переход для страницы, установите ключ pageTransition в definePageMeta страницы:

<script setup lang="ts">
definePageMeta
({
pageTransition
: {
name
: 'rotate'
} }) </script>

Переход на страницу «О нас» добавит эффект 3D-вращения:

Переходы лейаутов

Вы можете включить переходы лейаутов, чтобы применить автоматический переход для всех лейаутов.

nuxt.config.ts
export default 
defineNuxtConfig
({
app
: {
layoutTransition
: {
name
: 'layout',
mode
: 'out-in' }
}, })

Чтобы начать добавлять переходы между страницами и лейаутами, добавьте следующий CSS в ваш app.vue:

<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

<style>
.layout-enter-active,
.layout-leave-active {
  transition: all 0.4s;
}
.layout-enter-from,
.layout-leave-to {
  filter: grayscale(1);
}
</style>

Это дает следующий результат при навигации между страницами:

Подобно pageTransition, вы можете применить пользовательский layoutTransition к компоненту страницы, используя definePageMeta:

pages/about.vue
<script setup lang="ts">
definePageMeta
({
layout
: 'orange',
layoutTransition
: {
name
: 'slide-in'
} }) </script>

Глобальные настройки

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

Оба ключа pageTransition и layoutTransition принимают TransitionProps как сериализуемые значения JSON, в которые можно передать name, mode и другие допустимые свойства пользовательского перехода CSS.

nuxt.config.ts
export default 
defineNuxtConfig
({
app
: {
pageTransition
: {
name
: 'fade',
mode
: 'out-in' // по умолчанию
},
layoutTransition
: {
name
: 'slide',
mode
: 'out-in' // по умолчанию
} } })
Если вы измените свойство name, вам также придется соответствующим образом переименовать CSS-классы.

Чтобы переопределить глобальное свойство перехода, используйте definePageMeta, чтобы определить переходы страниц или лейаутов для одной страницы Nuxt и переопределить любые переходы страниц или лейаутов, которые определены глобально в файле nuxt.config.

pages/some-page.vue
<script setup lang="ts">
definePageMeta
({
pageTransition
: {
name
: 'bounce',
mode
: 'out-in' // по умолчанию
} }) </script>

Отключение переходов

pageTransition и layoutTransition можно отключить для определенного маршрута:

pages/some-page.vue
<script setup lang="ts">
definePageMeta
({
pageTransition
: false,
layoutTransition
: false
}) </script>

Или глобально в nuxt.config:

nuxt.config.ts
export default 
defineNuxtConfig
({
app
: {
pageTransition
: false,
layoutTransition
: false
} })

Хуки JavaScript

Для расширенных вариантов использования вы можете использовать JavaScript-хуки для создания высокодинамичных и настраиваемых переходов для страниц Nuxt.

Этот способ представляет собой идеальный пример использования библиотек анимации JavaScript, таких как GSAP.

pages/some-page.vue
<script setup lang="ts">
definePageMeta
({
pageTransition
: {
name
: 'custom-flip',
mode
: 'out-in',
onBeforeEnter
: (
el
) => {
console
.
log
('Перед появлением...')
},
onEnter
: (
el
,
done
) => {},
onAfterEnter
: (
el
) => {}
} }) </script>
Узнайте больше о дополнительных JavaScript-хуках, доступных в компоненте Transition.

Динамические переходы

Чтобы применить динамические переходы с использованием условной логики, вы можете использовать встроенные middleware, чтобы назначить другое имя перехода для to.meta.pageTransition.

<script setup lang="ts">
definePageMeta
({
pageTransition
: {
name
: 'slide-right',
mode
: 'out-in'
},
middleware
(
to
,
from
) {
if (
to
.
meta
.
pageTransition
&& typeof
to
.
meta
.
pageTransition
!== 'boolean')
to
.
meta
.
pageTransition
.
name
= +
to
.
params
.
id
! > +
from
.
params
.
id
! ? 'slide-left' : 'slide-right'
} }) </script> <template> <
h1
>#{{
$route
.
params
.
id
}}</
h1
>
</template> <style> .slide-left-enter-active, .slide-left-leave-active, .slide-right-enter-active, .slide-right-leave-active { transition: all 0.2s; } .slide-left-enter-from { opacity: 0; transform: translate(50px, 0); } .slide-left-leave-to { opacity: 0; transform: translate(-50px, 0); } .slide-right-enter-from { opacity: 0; transform: translate(-50px, 0); } .slide-right-leave-to { opacity: 0; transform: translate(50px, 0); } </style>

Теперь страница применяет переход slide-left при переходе к следующему идентификатору и slide-right для предыдущего:

Переход с NuxtPage

Когда <NuxtPage /> используется в app.vue, переходы могут быть настроены с помощью свойства transition, чтобы активировать переходы глобально.

app.vue
<template>
  <div>
    <NuxtLayout>
      <NuxtPage :transition="{
        name: 'bounce',
        mode: 'out-in'
      }" />
    </NuxtLayout>
  </div>
</template>
Помните, что этот переход страниц нельзя переопределить с помощью definePageMeta на отдельных страницах.

View Transitions API (экспериментально)

Nuxt поставляется с экспериментальной реализацией View Transitions API (см. MDN). Это захватывающий новый способ реализации собственных переходов браузера, которые (помимо прочего) позволяют осуществлять переходы между несвязанными элементами на разных страницах.

Вы можете ознакомиться с демо-версией на сайте https://nuxt-view-transitions.surge.sh и исходным кодом на StackBlitz.

Интеграция Nuxt находится в стадии активной разработки, но ее можно включить с помощью параметра experimental.viewTransition в файле конфигурации:

nuxt.config.ts
export default 
defineNuxtConfig
({
experimental
: {
viewTransition
: true
} })

Возможные значения: false, true или always.

Если установлено значение true, Nuxt не будет применять переходы, если браузер пользователя соответствует prefers-reduced-motion: reduce (рекомендуется). Если установлено значение always, Nuxt всегда будет применять переход, и вам решать, следует ли уважать предпочтения пользователя.

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

nuxt.config.ts
export default 
defineNuxtConfig
({
app
: {
// Отключите переходы между представлениями глобально и включите их для каждой страницы
viewTransition
: false
}, })

Можно переопределить значение viewTransition по умолчанию для страницы, установив ключ viewTransition в definePageMeta страницы:

pages/about.vue
<script setup lang="ts">
definePageMeta
({
viewTransition
: false
}) </script>
Переопределение переходов представлений на уровне страницы будет иметь эффект только в том случае, если включена опция experimental.viewTransition.

Если вы также используете переходы Vue, такие как pageTransition и layoutTransition (см. выше), чтобы достичь того же результата, что и в новом View Transitions API, то вы можете захотеть отключить переходы Vue, если браузер пользователя поддерживает более новый, нативный Web API. Вы можете сделать это, создав ~/middleware/disable-vue-transitions.global.ts со следующим содержимым:

export default defineNuxtRouteMiddleware(to => {
  if (import.meta.server || !document.startViewTransition) { return }

  // Отключить встроенные переходы Vue
  to.meta.pageTransition = false
  to.meta.layoutTransition = false
})

Известные проблемы

  • Если вы выполняете выборку данных в setup-функциях страниц, возможно, на данный момент вам стоит пересмотреть использование этой возможности. (По замыслу, View Transitions полностью блокируют обновления DOM на время их выполнения.) Мы рассматриваем возможность ограничить View Transition последними моментами перед разрешением <Suspense>, но пока вам стоит тщательно обдумать, стоит ли использовать эту функцию, если это касается вас.