- Aprender
-
Ecosistema
Ayuda
Herramientas
Librerías Oficiales
Noticias
Lista de Recursos
- Equipo
- Apoyar Vue
- Traducciones
Guía
Conocimientos Esenciales
- Instalación
- Introducción
- La instancia Vue
- Sintaxis de Template
- Propiedades Computadas y Observadores
- Enlace Clases y Estilos
- Renderización Condicional
- Renderizado de lista
- Manejo de eventos
- Binding en Formularios
- Conceptos Básicos de Componentes
Transiciones & Animaciones
- Efectos de Transición
Componentes en Profundidad
- Registro de Componente
- Propiedades
- Eventos personalizados
- Slots
- Componentes Dinámicos & Asíncronos
- Handling Edge Cases
- Transiciones de estado
Reusabilidad & Composición
- Mixins
- Directivas Personalizadas
- Funciones de renderizado & JSX
- Plugins
- Filtros
- Publicación en Producción
Herramientas
- Componentes de un Solo Archivo (Single File Components)
- Testing Unitario
- Soporte TypeScript
Escalando la Aplicación
- Enrutamiento
- Administración del Estado
- Renderizado del lado de Servidor
Funcionamiento Interno
- Reactividad en profundidad
Migraciones
- Migración desde Vue 1.x
- Migración desde Vue Router 0.7.x
- Migración de Vuex 0.6.x a 1.0
Meta Documentación
- Comparación con otros frameworks
- Únete a la comunidad Vue.js!
- Conozca al equipo
Efectos de Transición
Introducción
Vue ofrece una variedad de maneras para aplicar efectos de transición cuando los elementos son insertados, actualizados o eliminados del DOM. Esto incluye herramientas para:
- aplicar clases para transiciones y animaciones CSS automáticamente
- integrar librerías externas de animación CSS, por ejemplo Animate.css
- usar JavaScript para manipular directamente el DOM durante hooks de transición
- integrar librerías externas de animación por JavaScript, como Velocity.js
En esta página, únicamente vamos a cubrir las transiciones de entrada, salida, y lista, pero puede ver la siguiente sección para controlar transiciones de estado.
Transiciones para Elementos/Componentes sencillos
Vue ofrece un componente de envoltura transition
, que le permite añadir transiciones de entrada/salida para cualquier elemento o componente en los siguientes contextos:
- Renderización condicional (usando
v-if
) - Visualización condicional (usando
v-show
) - Componentes dinámicos
- Nodos raíz de componentes
Así es como se ve un ejemplo sencillo en acción:
<div id="demo"> |
new Vue({ |
.fade-enter-active, .fade-leave-active { |
hola
Cuando un elemento envuelto en un componente transition
es insertado o eliminado, ésto es lo que sucede:
Vue determinará automáticamente si el elemento objetivo tiene transiciones o animaciones CSS aplicadas. Si las tiene, las clases de transición CSS serán añadidas/removidas en los momentos apropiados.
Si el componente de transición ha ofrecido hooks de JavaScript, éstos serán invocados en los momentos apropiados.
Si no son detectadas animaciones/transiciones CSS y no se han dado hooks de Javascript, las operaciones DOM para insertar y/o eliminar serán ejecutadas inmediatamente en el siguiente frame (Tenga en cuenta: hablamos de un frame de animación de navegador, es diferente al concepto de
nextTick
de Vue).
Clases de Transición
Existen cuatro clases aplicadas para transiciones de entrada/salida.
v-enter
: Estado inicial para entrada. Aplicada antes que el elemento sea insertado, se elimina después de un frame.v-enter-active
: Estado activo y de finalización para entrada. Aplicada antes que el elemento sea insertado, se elimina cuando la animación/transición finaliza.v-leave
: Estado inicial para salida. Aplicada cuando la transición de salida es activada, se elimina después de un frame.v-leave-active
: Estado activo y de finalización para salida. Aplicada cuando la transición de salida es activada, se elimina cuando la animación/transición finaliza.
Cada una de estas clases usará un prefijo con el nombre de la transición. Aquí, el prefijo v-
representa el prefijo por defecto cuando usa un elemento <transition>
sin nombre. Si usa <transition name="mi-transicion">
por ejemplo, entonces la clase v-enter
debe llamarse mi-transicion-enter
.
v-enter-active
y v-leave-active
le da a usted la capacidad de especificar diferentes curvas de suavizado para transiciones de entrada/salida, lo cual podrá verlo en un ejemplo de la siguiente sección.
Transiciones CSS
Uno de los tipos de transición más comunes usa transiciones CSS. Aquí hay un ejemplo sencillo:
<div id="example-1"> |
new Vue({ |
/* Las animaciones de entrada y salida pueden usar */ |
hola
Animaciones CSS
Las animaciones CSS son aplicadas de la misma forma que las transiciones CSS, la diferencia es que v-enter
no es eliminado inmediatamente después que el elemento sea insertado, sino que se elimina en el evento animationend
.
Aquí hay un ejemplo, omitiendo las reglas con prefijo de CSS para mayor brevedad.
<div id="example-2"> |
new Vue({ |
.bounce-enter-active { |
Mírame!
Clases de Transición Personalizadas
Usted también puede especificar clases de transición personalizadas cuando usa los siguientes atributos:
enter-class
enter-active-class
enter-to-class
(2.1.8+)leave-class
leave-active-class
leave-to-class
(2.1.8+)
Estas van a sobreescribir los nombres convencionales de las clases. Esto es especialmente útil cuando desea combinar el sistema de transición de Vue con una librería de animaciones CSS existente, como Animate.css.
Por ejemplo:
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css"> |
new Vue({ |
hola
Usando Animaciones y Trancisiones Juntas
Vue necesita agregar listeners de eventos para poder saber cuándo una transición ha finalizado. Puede ser mediante transitionended
o animationended
, dependiendo del tipo de reglas CSS aplicadas. Si únicamente está usando la una o la otra, Vue detecta automáticamente el tipo correcto.
Sin embargo, en algunos casos usted desea tener ambos tipos en el mismo elemento, por ejemplo tener una animación CSS activada por Vue, junto a un efecto de transición en el hover. En estos casos, debe declarar explícitamente el tipo que quiera que Vue use, usando el atributo type
, con un valor ya sea de animation
o transition
.
Hooks de JavaScript
Usted también puede definir hooks de JavaScript en los atributos:
<transition |
// ... |
Estos hooks pueden ser usados junto a transiciones/animaciones CSS o por cuenta propia.
Cuando use transiciones JavaScript, los callbacks done
son requeridos para los hooks enter
y leave
. De otra forma, serán llamados síncronamente y la transición finalizará imediatamente.
También es buena idea añadir explícitamente v-bind:css="false"
para las transiciones JavaScript, de modo que Vue pueda obviar la detección de CSS. Esto también previene que algunas reglas CSS accidentalmente interfieran en la transición.
Ahora veamos un ejemplo. Aquí hay una transición sencilla en JavaScript usando Velocity.js:
<!-- |
new Vue({ |
Demo
Transiciones en Renderizado Inicial
Si usted quisiera también aplicar una transición en la renderización inicial de un nodo, puede añadir el atributo appear
:
<transition appear> |
Por defecto, esto usará la transición especificada para entrada y salida. Sin embargo, si lo quisiera, puede también especificar clases CSS personalizadas:
<transition |
y hooks de JavaScript personalizados:
<transition |
Transiciones Entre Elementos
Ya discutiremos las transiciones entre componentes más adelante, pero también puede aplicar transiciones entre elementos básicos usando v-if
/v-else
. Una de las transiciones entre dos elementos más comunes es la que se usa entre un contenedor de lista, y un mensaje describiendo una lista vacía:
<transition> |
Funciona bien, pero hay un inconveniente que debemos tener en cuenta:
Cuando intercambia elementos que tienen el mismo nombre de etiqueta, debe decirle a Vue que ellos son elementos diferentes usando atributos key
únicos. De otra forma, el compilador de Vue únicamente reemplazará el contenido del elemento para mejorar la eficiencia. Aún cuando sea innecesario, es considerado buena práctica siempre usar key
en múltiples elementos dentro de un componente <transition>
.
Por ejemplo:
<transition> |
En estos casos, puede también usar el atributo key
para realizar una trancisión entre estados diferentes del mismo elemento. En vez de usar v-if
y v-else
, el ejemplo anterior puede ser re-escrito como:
<transition> |
Es posible realizar una transición entre cualquier número de elementos, ya sea usando muchos v-if
, o asignando una propiedad dinámica a un elemento. Por ejemplo:
<transition> |
Que también puede ser escrito de la siguiente forma:
<transition> |
// ... |
Modos de Transición
Aún se presenta un problema. Intente hacer click sobre el botón:
Mientras se hace la transición entre el botón “on” y el botón “off”, ambos botones son renderizados - uno realizando la transición de salida mientras el otro realiza la de entrada. Este comportamiento ocurre por defecto en <transition>
- las entradas y salidas suceden simultáneamente.
Algunas veces funciona genial, por ejemplo cuando estamos realizando transiciones entre elementos ubicados absolutamente unos encima de otros:
O también cuando se trasladan para que parezcan transiciones de deslizamiento:
Sin embargo, transiciones de entrada y salida simultáneas no siempre son deseables, de modo que Vue ofrece nodos de transición alternativos:
in-out
: El nuevo elemento realiza la transición de entrada, cuando haya terminado, el elemento actual realiza su transición de salida.out-in
: El elemento actual realiza su transición de salida, cuando haya terminado, el nuevo elemento realiza su transición de entrada.
Ahora actualicemos las transiciones para nuestros botones on/off con out-in
:
<transition name="fade" mode="out-in"> |
Con sólo añadir un sencillo atributo, hemos arreglado la transición original sin tener que agregar estilos especiales.
El modo in-out
no es usado a menudo, pero a veces puede ser útil para un efecto de transición ligeramente diferente. Intentemos combinarlo con la transición slide-fade con la que trabajamos anteriormente:
Se vé genial, ¿no?
Transiciones Entre Componentes
Las transiciones entre componentes son aún más sencillas - ni siquiera necesitamos el atributo key
. En su lugar, sólo envolvemos un componente dinámico:
<transition name="component-fade" mode="out-in"> |
new Vue({ |
.component-fade-enter-active, .component-fade-leave-active { |
Transiciones de Listas
Hasta ahora, hemos logrado realizar transiciones para:
- Nodos individuales
- Múltiples nodos donde sólo uno es renderizado a la vez
¿Qué tenemos para el caso en que tengamos una lista completa de elementos que queramos renderizar simultáneamente, por ejemplo con v-for
? En ese caso, usaremos el componente <transition-group>
. Pero antes que lo veamos en un ejemplo, hay algunas cosas que es importante conocer sobre éste componente.
- A diferencia de
<transition>
, renderiza un elemento<span>
por defecto. Puede cambiar el elemento que es renderizado con el atributotag
. - Los elementos contenidos siempre requieren tener un atributo único
key
Transiciones de Entrada/Salida en Listas
Ahora veamos un ejemplo sencillo, transiciones de entrada y salida usando las mismas clases CSS que hemos usado anteriormente:
<div id="list-demo"> |
new Vue({ |
.list-item { |
Hay un problema presente en este ejemplo. Cuando agrega o remueve un elemento, los que están alrededor saltan instantáneamente a su nueva ubicación en vez de realizar una transición suave. Eso lo arreglaremos más adelante.
Transiciones de Movimiento en Listas
El componente <transition-group>
tiene otro truco bajo su manga. No sólo puede animar las entradas y salidas, sino también cambios en la posición. El único nuevo concepto que debe conocer para usar esta característica es la adición de la clase v-move
, la cual es añadida cuando los elementos están cambiando de posición. Como con las otras clases, su prefijo será el mismo que el valor que le haya asignado al atributo name
, y también puede especificar una clase CSS con el atributo move-class
.
Esta clase es muy útil para especificar el tiempo y la curva de suavizado de la transición, como verá a continuación:
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script> |
new Vue({ |
.flip-list-move { |
Esto podrá parecer magia, pero por debajo, Vue está usando una sencilla técnica de animación llamada FLIP para realizar las transiciones de los elementos suavemente de su antigua posición a la nueva usando transformaciones.
¡Podemos combinar esta técnica con nuestra implementación anterior para animar cualquier cambio posible en nuestra lista!
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script> |
new Vue({ |
.list-complete-item { |
Algo importante para tener en cuenta es que éstas transiciones FLIP no funcionan en elementos con display: inline
. Como alternativa, puede usar display: inline-block
o ubicar los elementos en un contexto flexible.
Estas animaciones FLIP no están limitadas a un eje particular. Los elementos en una grilla multidimensional pueden realizar transiciones igual de fácil:
Continúa apretando el botón mezclar hasta que ganes.
Retardando Transiciones de Lista
Es posible retardar transiciones en una lista usando atributos de datos para comunicarse con transciones JavaScript:
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script> |
new Vue({ |
Transiciones Reusables
Las transiciones pueden ser reusadas a través del sistema de componentes de Vue. Para crear una transición reusable, todo lo que debe hacer es ubicar un componente <transition>
o <transition-group>
en la raíz, luego enviar cualquier hijo en el componente de transición.
Aquí hay un ejemplo usando un componente de plantilla:
Vue.component('my-special-transition', { |
Y los componentes funcionales son especialmente efectivos para ésta tarea:
Vue.component('my-special-transition', { |
Transiciones Dinámicas
Sí, ¡incluso las transiciones en Vue son controladas por datos! El ejemplo más básico de una transición dinámica es asignar el atributo name
a una propiedad dinámica.
<transition v-bind:name="transitionName"> |
Esto puede ser útil cuando ha definido animaciones/transiciones CSS usando las convenciones de clases de transición de Vue y simplemente quiere cambiar entre ellas.
Pero en realidad, cualquier transición puede ser asignada dinámicamente. Y no son sólo atributos. Ya que los hooks de eventos son métodos, tienen acceso a cualquier dato del contexto. Esto significa que, dependiendo del estado de su componente, sus transiciones pueden comportarse de forma diferente.
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script> |
new Vue({ |
hola
Finalmente, la mejor forma de crear transiciones dinámicas es a través de componentes que aceptan props para cambiar la naturaleza de la transición a ser usada. Puede sonar como cliché, pero el único límite realmente es su imaginación.