nuxt logo

Traducción de Documentación (No Oficial)

Transiciones

Aplica transiciones entre páginas y diseños con Vue o transiciones de vista nativas del navegador.

Nuxt aprovecha el componente <Transition> de Vue para aplicar transiciones entre páginas y diseños.

Transiciones de Página

Puedes habilitar transiciones de página para aplicar una transición automática a todas tus páginas.

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

Si estás cambiando tanto diseños como páginas, la transición de página que configures aquí no se ejecutará. En su lugar, deberías configurar una transición de diseño.

Para comenzar a agregar transiciones entre tus páginas, añade el siguiente CSS a tu 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>

Esto produce el siguiente resultado al navegar entre páginas:

Para establecer una transición diferente para una página, configura la clave pageTransition en definePageMeta de la página:

definePageMeta({
  pageTransition: {
    name: 'rotate'
  }
})

Moverse a la página sobre añadirá el efecto de rotación 3D:

Transiciones de Diseño

Puedes habilitar transiciones de diseño para aplicar una transición automática a todos tus diseños.

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

Para comenzar a agregar transiciones entre tus páginas y diseños, añade el siguiente CSS a tu 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>

Esto produce el siguiente resultado al navegar entre páginas:

Similar a pageTransition, puedes aplicar una layoutTransition personalizada al componente de la página usando definePageMeta:

pages/about.vue
definePageMeta({
  layout: 'orange',
  layoutTransition: {
    name: 'slide-in'
  }
})

Configuraciones Globales

Puedes personalizar estos nombres de transición predeterminados globalmente usando nuxt.config.

Tanto las claves pageTransition como layoutTransition aceptan TransitionProps como valores serializables en JSON donde puedes pasar el name, mode y otros props de transición válidos del CSS personalizado.

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    pageTransition: {
      name: 'fade',
      mode: 'out-in' // predeterminado
    },
    layoutTransition: {
      name: 'slide',
      mode: 'out-in' // predeterminado
    }
  }
})

Si cambias la propiedad name, también debes renombrar las clases CSS en consecuencia.

Para sobrescribir la propiedad de transición global, usa definePageMeta para definir transiciones de página o diseño para una sola página de Nuxt y sobrescribir cualquier transición de página o diseño que esté definida globalmente en el archivo nuxt.config.

pages/some-page.vue
definePageMeta({
  pageTransition: {
    name: 'bounce',
    mode: 'out-in' // predeterminado
  }
})

Desactivar Transiciones

pageTransition y layoutTransition pueden desactivarse para una ruta específica:

pages/some-page.vue
definePageMeta({
  pageTransition: false,
  layoutTransition: false
})

O globalmente en el nuxt.config:

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

Hooks de JavaScript

Para casos de uso avanzados, puedes usar hooks de JavaScript para crear transiciones altamente dinámicas y personalizadas para tus páginas de Nuxt.

Esta forma presenta casos de uso perfectos para bibliotecas de animación de JavaScript como GSAP.

pages/some-page.vue
definePageMeta({
  pageTransition: {
    name: 'custom-flip',
    mode: 'out-in',
    onBeforeEnter: (el) => {
      console.log('Antes de entrar...')
    },
    onEnter: (el, done) => {},
    onAfterEnter: (el) => {}
  }
})

Aprende más sobre los hooks de JavaScript adicionales disponibles en el componente Transition.

Transiciones Dinámicas

Para aplicar transiciones dinámicas usando lógica condicional, puedes aprovechar el middleware en línea para asignar un nombre de transición diferente a 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>

La página ahora aplica la transición slide-left al ir al siguiente id y slide-right para el anterior:

Transición con NuxtPage

Cuando se usa <NuxtPage /> en app.vue, las transiciones pueden configurarse con el prop transition para activar transiciones globalmente.

app.vue
<template>
  <div>
    <NuxtLayout>
      <NuxtPage :transition="{
        name: 'bounce',
        mode: 'out-in'
      }" />
    </NuxtLayout>
  </div>
</template>

Recuerda, esta transición de página no puede ser sobrescrita con definePageMeta en páginas individuales.

API de Transiciones de Vista (experimental)

Nuxt viene con una implementación experimental de la API de Transiciones de Vista (ver MDN). Esta es una nueva forma emocionante de implementar transiciones nativas del navegador que (entre otras cosas) tienen la capacidad de transicionar entre elementos no relacionados en diferentes páginas.

Puedes ver una demostración en https://nuxt-view-transitions.surge.sh y el código fuente en StackBlitz.

La integración de Nuxt está en desarrollo activo, pero puede habilitarse con la opción experimental.viewTransition en tu archivo de configuración:

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

Los valores posibles son: false, true, o 'always'.

Si se establece en true, Nuxt no aplicará transiciones si el navegador del usuario coincide con prefers-reduced-motion: reduce (recomendado). Si se establece en always, Nuxt siempre aplicará la transición y depende de ti respetar la preferencia del usuario.

Por defecto, las transiciones de vista están habilitadas para todas las páginas, pero puedes establecer un valor predeterminado global diferente.

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    // Desactivar transiciones de vista globalmente, y optar por página individualmente
    viewTransition: false
  },
})

Es posible sobrescribir el valor predeterminado de viewTransition para una página configurando la clave viewTransition en definePageMeta de la página:

pages/about.vue
definePageMeta({
  viewTransition: false
})

Sobrescribir transiciones de vista por página solo tendrá efecto si has habilitado la opción experimental.viewTransition.

Si también estás usando transiciones de Vue como pageTransition y layoutTransition (ver arriba) para lograr el mismo resultado que la nueva API de Transiciones de Vista, entonces puede que desees desactivar las transiciones de Vue si el navegador del usuario soporta la nueva API web nativa. Puedes hacer esto creando ~/middleware/disable-vue-transitions.global.ts con el siguiente contenido:

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

  // Desactivar transiciones integradas de Vue
  to.meta.pageTransition = false
  to.meta.layoutTransition = false
})

Problemas Conocidos

  • Si realizas la obtención de datos dentro de las funciones de configuración de tu página, es posible que desees reconsiderar el uso de esta función por el momento. (Por diseño, las Transiciones de Vista congelan completamente las actualizaciones del DOM mientras se llevan a cabo.) Estamos buscando restringir la Transición de Vista a los momentos finales antes de que <Suspense> se resuelva, pero mientras tanto, es posible que desees considerar cuidadosamente si adoptar esta función si esto te describe.