tutoriales.com

Creando Animaciones y Transiciones Fluídas en Vue 3 con Transition y TransitionGroup

Descubre cómo dar vida a tus aplicaciones web en Vue 3 mediante la implementación de animaciones y transiciones fluidas para elementos individuales y listas dinámicas utilizando clases CSS y JavaScript.

Intermedio9 min de lectura3 views
Reportar error

Introducción a las Animaciones en Vue 3 🚀

Las animaciones y transiciones son elementos fundamentales en el desarrollo web moderno. No solo mejoran la estética visual de una aplicación, sino que también proporcionan una experiencia de usuario (UX) superior al guiar la atención del usuario, indicar cambios de estado y suavizar la aparición o desaparición de elementos en el DOM.

En Vue 3, manejar estas animaciones es sumamente sencillo gracias al componente nativo <Transition> y su contraparte para listas <TransitionGroup>. A lo largo de este tutorial completo, exploraremos cómo aprovechar al máximo estas herramientas para transformar interfaces estáticas en experiencias dinámicas y atractivas.

💡 Consejo: Las mejores animaciones son aquellas que pasan desapercibidas pero mejoran la fluidez percibida de la aplicación. Evita animaciones demasiado lentas o recargadas.

El Componente nativo 🎬

Cuando un elemento envuelto en el componente <Transition> es insertado o eliminado del DOM, Vue detecta automáticamente si el elemento tiene transiciones CSS o animaciones aplicadas. Si es así, añade o remueve clases CSS en momentos específicos del ciclo de vida de la transición.

Las 6 Clases de Transición

Para entender cómo opera el componente <Transition>, es vital conocer las seis clases que Vue inyecta automáticamente durante el proceso:

Clase CSSDescripciónMomento de Aplicación
v-enter-fromEstado inicial de entrada.Se añade antes de insertar el elemento, se quita un fotograma después.
v-enter-activeEstado activo de entrada.Se aplica durante toda la fase de entrada (desde el inicio hasta que termina la transición).
v-enter-toEstado final de entrada.Se añade un fotograma después de la inserción, se quita al finalizar la transición.
v-leave-fromEstado inicial de salida.Se añade inmediatamente cuando se activa la transición de salida.
v-leave-activeEstado activo de salida.Se aplica durante toda la fase de salida (desde el inicio hasta que desaparece el elemento).
v-leave-toEstado final de salida.Se añade un fotograma después de iniciar la salida, se quita al terminar.
Ciclo de Vida de Transition en Vue 3 FASE DE ENTRADA (Aparecer) v-enter-from Estado inicial v-enter-to Estado final v-enter-active (Duración, Curva, Delay) FASE DE SALIDA (Desaparecer) v-leave-from Estado inicial v-leave-to Estado final v-leave-active (Duración, Curva, Delay)

Ejemplo Práctico: Desvanecimiento Simple (Fade)

Vamos a construir nuestro primer ejemplo implementando una transición de desvanecimiento (fade) en un componente de Vue 3 utilizando Composition API.

<script setup>
import { ref } from 'vue'

const mostrar = ref(true)
</script>

<template>
  <div class="demo-container">
    <button @click="mostrar = !mostrar">
      {{ mostrar ? 'Ocultar' : 'Mostrar' }} Mensaje
    </button>

    <Transition>
      <p v-if="mostrar" class="mensaje">¡Hola, este texto se anima suavemente!</p>
    </Transition>
  </div>
</template>

<style>
.mensaje {
  padding: 1rem;
  background-color: #e0f2fe;
  border-left: 4px solid #0284c7;
  margin-top: 1rem;
}

/* Definimos las clases de transición */
.v-enter-active,
.v-leave-active {
  transition: opacity 0.5s ease;
}

.v-enter-from,
.v-leave-to {
  opacity: 0;
}
</style>
📌 Nota: Si no le das un nombre al componente <Transition> (ej. <Transition name="mi-transicion">), por defecto utilizará el prefijo v- para las clases CSS.

Transiciones con Nombres Personalizados 🏷️

A medida que tu aplicación crezca, necesitarás múltiples transiciones con comportamientos diferentes. Para evitar conflictos entre clases CSS, puedes utilizar la propiedad name en el componente <Transition>.

Ejemplo de Transición 'Slide' (Desplazamiento)

Imagina que queremos que un elemento se desplace desde la derecha al aparecer:

<script setup>
import { ref } from 'vue'

const activo = ref(false)
</script>

<template>
  <button @click="activo = !activo">Alternar Desplazamiento</button>

  <Transition name="slide">
    <div v-if="activo" class="caja-deslizante">
      Panel Lateral Animado
    </div>
  </Transition>
</template>

<style>
.caja-deslizante {
  width: 250px;
  padding: 20px;
  background: #f3f4f6;
  border: 1px solid #d1d5db;
}

.slide-enter-active,
.slide-leave-active {
  transition: transform 0.4s ease, opacity 0.4s ease;
}

.slide-enter-from,
.slide-leave-to {
  transform: translateX(50px);
  opacity: 0;
}
</style>
🔥 Importante: Asegúrate de combinar propiedades como transform y opacity en lugar de propiedades que modifique el layout (como width o margin) para garantizar un rendimiento óptimo a 60 FPS.

Animaciones en Listas con 📋

Mientras que el componente <Transition> está diseñado para un solo elemento o nodo raíz, <TransitionGroup> se utiliza para manejar listas donde múltiples elementos pueden ser añadidos, eliminados o reordenados.

Características Clave de TransitionGroup:

Renderizado de Etiqueta: Por defecto, no renderiza un elemento contenedor en el DOM, pero puedes especificar una etiqueta usando la prop tag="ul" o similar.
Clases de Movimiento: Incluye automáticamente la clase v-move que permite animar los elementos cuando cambia su posición dentro de la lista.
Claves Obligatorias: Cada hijo dentro de un <TransitionGroup> debe tener un atributo :key único y estable.

Ejemplo Práctico: Lista de Tareas Dinámica

<script setup>
import { ref } from 'vue'

const tareas = ref(['Aprender Vue 3', 'Dominar TransitionGroup', 'Crear una App Increíble'])
const nuevaTarea = ref('')

const agregarTarea = () => {
  if (nuevaTarea.value.trim() !== '') {
    tareas.value.push(nuevaTarea.value)
    nuevaTarea.value = ''
  }
}

const eliminarTarea = (index) => {
  tareas.value.splice(index, 1)
}
</script>

<template>
  <div class="lista-container">
    <input v-model="nuevaTarea" @keyup.enter="agregarTarea" placeholder="Escribe una nueva tarea..." />
    <button @click="agregarTarea">Agregar</button>

    <TransitionGroup name="lista" tag="ul">
      <li v-for="(tarea, index) in tareas" :key="tarea" class="item-lista">
        <span>{{ tarea }}</span>
        <button @click="eliminarTarea(index)">X</button>
      </li>
    </TransitionGroup>
  </div>
</template>

<style>
.lista-enter-active,
.lista-leave-active {
  transition: all 0.5s ease;
}

.lista-enter-from,
.lista-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

/* Animación para los elementos que cambian de posición */
.lista-move {
  transition: transform 0.5s ease;
}

.item-lista {
  display: flex;
  justify-content: space-between;
  padding: 8px 12px;
  margin-top: 5px;
  background: #f9fafb;
  border: 1px solid #e5e7eb;
}
</style>

Integración con Librerías de Terceros (Animate.css) 🎨

Si no deseas escribir tus propias animaciones CSS desde cero, puedes integrar fácilmente librerías externas como Animate.css utilizando atributos de clase dedicados en el componente <Transition>.

Atributos de Clase Personalizados:

  • enter-from-class
  • enter-active-class
  • enter-to-class
  • leave-from-class
  • leave-active-class
  • leave-to-class

Ejemplo de Integración

<template>
  <Transition
    name="custom"
    enter-active-class="animate__animated animate__fadeInDown"
    leave-active-class="animate__animated animate__fadeOutUp"
  >
    <p v-if="mostrar">¡Animado con Animate.css!</p>
  </Transition>
</template>
💡 Consejo: Esta técnica es ideal para proyectos donde necesitas un catálogo amplio de animaciones listas para usar sin escribir código CSS complejo.

Ganchos de JavaScript para Animaciones Avanzadas ⚙️

Cuando las animaciones CSS se quedan cortas (por ejemplo, al crear efectos basados en física, animaciones de canvas o librerías como GSAP), puedes recurrir a los ganchos de JavaScript proporcionados por el componente <Transition>.

Lista de Ganchos Disponibles:

  • @before-enter
  • @enter
  • @after-enter
  • @enter-cancelled
  • @before-leave
  • @leave
  • @after-leave
  • @leave-cancelled

Ejemplo con JavaScript y GSAP

<script setup>
import { ref } from 'vue'
import gsap from 'gsap'

const visible = ref(false)

const onEnter = (el, done) => {
  gsap.fromTo(el, 
    { opacity: 0, scale: 0.2 }, 
    { opacity: 1, scale: 1, duration: 0.5, onComplete: done }
  )
}

const onLeave = (el, done) => {
  gsap.to(el, 
    { opacity: 0, scale: 0.2, duration: 0.5, onComplete: done }
  )
}
</script>

<template>
  <button @click="visible = !visible">Alternar GSAP</button>

  <Transition
    @enter="onEnter"
    @leave="onLeave"
    :css="false"
  >
    <div v-if="visible" class="caja-gsap">
      Animado con GSAP
    </div>
  </Transition>
</template>

<style>
.caja-gsap {
  width: 150px;
  height: 150px;
  background: #10b981;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>
⚠️ Advertencia: Cuando utilices ganchos de JavaScript exclusivamente, asegúrate de añadir la prop :css="false". Esto evita que Vue intente detectar clases CSS y mejora ligeramente el rendimiento.

Resumen y Buenas Prácticas 🎯

Las transiciones y animaciones en Vue 3 aportan un valor estético y funcional incalculable a cualquier desarrollo web moderno. Para concluir, repasemos los puntos más importantes:

  • Utiliza <Transition> para elementos individuales y <TransitionGroup> para colecciones de elementos.
  • Prioriza propiedades optimizadas para GPU como transform y opacity.
  • Aprovecha las clases personalizadas para integrar librerías externas como Animate.css.
  • Utiliza ganchos de JavaScript cuando requieras un control milimétrico o interpolaciones complejas.
¿Preguntas Frecuentes (FAQ) ¿Puedo animar elementos que se muestran con v-show? Sí, el componente Transition funciona exactamente igual tanto con v-if como con v-show. ¿Por qué mi TransitionGroup no anima el movimiento? Asegúrate de haber definido las reglas para la clase .v-move y que cada hijo tenga un atributo :key único.
Vue.js: ¿Qué herramienta usar? <Transition> Elemento Único Alternar v-if / v-show Transiciones de entrada y salida simples. CSS Transitions/Anims <TransitionGroup> Listas / Colecciones Elementos en v-for Maneja reordenamiento clase v-move aplicada. Listas dinámicas Hooks JS / GSAP Complejidad Alta Control total por código Líneas de tiempo (GSAP) Efectos dinámicos. Animaciones avanzadas

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!