1 Fundamentos de Transição
1.1 Métodos de Transição
O Vue oferece diversas maneiras de aplicar efeitos de transição ao inserir, atualizar ou remover elementos do DOM. As ferramentas disponíveis incluem:
- Aplicação automática de classes em transições e animações CSS
- Integração com bibliotecas de animação CSS de terceiros, como Animate.css
- Manipulação direta do DOM através de funções de gancho de transição
- Uso de bibliotecas de animação JavaScript de terceiros, como Velocity.js
1.2 Cenários de Transição
- Renderização condicional (utilizando
v-if) - Exibição condicional (utilizando
v-show) - Componentes dinâmicos
- Nó raiz do componente
1.3 Exemplo Básico de Transição
<template>
<div id="exemplo-transicao">
<button v-on:click="visivel = !visivel">
Alternar
</button>
<transition name="desvanecer">
<p v-if="visivel">Olá mundo</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
visivel: true
}
}
}
</script>
<style scoped>
.desvanecer-enter-active, .desvanecer-leave-active {
transition: opacity .5s;
}
.desvanecer-enter, .desvanecer-leave-to {
opacity: 0;
}
</style>
- Implementação de Transições com CSS
2.1 Clases de Transição
v-enter: Define o estado inicial da transição de entrada. É aplicado antes do elemento ser inserido e removido no próximo frame.v-enter-active: Define o estado ativo durante a transição de entrada. É aplicado durante toda a fase de entrada, antes do elemento ser inserido e removido após a conclusão da transição/animacao. Esta classe pode ser usada para definir a duração, atraso e função de curva da transição de entrada.v-enter-to: (Versão 2.1.8+) Define o estado final da transição de entrada. É aplicado no frame seguinte à inserção do elemento (quandov-enteré removido) e removido após a conclusão da transição/animacao.v-leave: Define o estado inicial da transição de saída. É aplicado imediatamente quando a transição de saída é disparada e removido no próximo frame.v-leave-active: Define o estado ativo durante a transição de saída. É aplicado durante toda a fase de saída, quando a transição é disparada e removido após a conclusão. Esta classe pode ser usada para definir a duração, atraso e função de curva da transição de saída.v-leave-to: (Versão 2.1.8+) Define o estado final da transição de saída. É aplicado no frame seguinte ao disparo da transição de saída (quandov-leaveé removido) e removido após a conclusão.
Para essas classes de transição, se você usar uma tag <transition> sem nome, v- será o prefixo padrão. Se usar <transition name="minha-transicao">, então v-enter será substituído por minha-transicao-enter.
2.2 Transição CSS
/* Configura diferentes animações para entrada e saída */
/* Define duração e função de animação */
.entrada-ativa {
transition: all .3s ease;
}
.saida-ativa {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.entrada, .saida-final
/* .slide-fade-saida-ativa para versões anteriores à 2.1.8 */ {
transform: translateX(10px);
opacity: 0;
}
2.3 Animação CSS
.entrada-ativa {
animation: bounce-in .5s;
}
.saida-ativa {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
2.4 Classes de Transição Personalizadas e Biblioetcas de Animação CSS
Podemos personalizar as classes de transição através dos seguintes atributos no componente <transition>:
- enter-class
- enter-active-class
- enter-to-class
(2.1.8+) - leave-class
- leave-active-class
- leave-to-class (2.1.8+)
Eles têm prioridade sobre as classes padrão, o que é útil para integrar o sistema de transição do Vue com bibliotecas de animação CSS de terceiros, como Animate.css.
<transition
name="transicao-classes-customizadas"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<p v-if="visivel">Olá</p>
</transition>
2.6 Definindo Duração da Transição
Em muitos casos, o Vue pode determinar automaticamente quando a transição termina. Por padrão, o Vue aguarda o primeiro evento transitionend ou animationend no elemento raiz da transição. No entanto, isso pode ser personalizado usando o atributo duration (em milissegundos):
<transition :duration="1000">...</transition>
Para definir durações diferentes para entrada e saída:
<transition :duration="{ enter: 500, leave: 800 }">...</transition>
3 Implementação de Transições com JavaScript
3.1 Ganchos (Hooks) JavaScript
<transition
v-on:before-enter="antesEntrada"
v-on:enter="entrada"
v-on:after-enter="aposEntrada"
v-on:enter-cancelled="entradaCancelada"
v-on:before-leave="antesSaida"
v-on:leave="saida"
v-on:after-leave="aposSaida"
v-on:leave-cancelled="saidaCancelada"
>
<!-- ... -->
</transition>
// ...
methods: {
// --------
// Durante a entrada
// --------
antesEntrada: function (el) {
// ...
},
// Esta função de callback é opcional
// Usada em conjunto com CSS
entrada: function (el, concluido) {
// ...
concluido()
},
aposEntrada: function (el) {
// ...
},
entradaCancelada: function (el) {
// ...
},
// --------
// Durante a saída
// --------
antesSaida: function (el) {
// ...
},
// Esta função de callback é opcional
// Usada em conjunto com CSS
saida: function (el, concluido) {
// ...
concluido()
},
aposSaida: function (el) {
// ...
},
// saidaCancelada é usada apenas com v-show
saidaCancelada: function (el) {
// ...
}
}
Ganchos JavaScript para Transições JavaScript
Ao usar apenas transições JavaScript, as funções de callback
concluidoementradaesaidasão obrigatórias. Caso contrário, elas serão chamadas de forma síncrona e a transição será concluída imediatamente.Recomenda-se adicionar
v-bind:css="false"aos elementos que usam apenas transições JavaScript para que o Vue pule a detecção de CSS, evitando interferências durante a transição.
3.2 Bibliotecas de Animação JavaScript de Terceiros
Exemplo com GSAP (GreenSock Animation Platform):
<transition
v-on:before-enter="antesEntrada"
v-on:enter="entrada"
v-on:leave="saida"
v-bind:css="false"
>
<p v-if="visivel">
Demonstração
</p>
</transition>
methods: {
antesEntrada: function (el) {
el.style.opacity = 0
el.style.transformOrigin = 'center'
},
entrada: function (el, concluido) {
gsap.to(el, {
opacity: 1,
scale: 1.2,
duration: 0.3,
onComplete: () => {
gsap.to(el, {
scale: 1,
duration: 0.2,
onComplete: concluido
})
}
})
},
saida: function (el, concluido) {
gsap.to(el, {
rotation: 45,
x: 50,
opacity: 0,
duration: 0.6,
onComplete: concluido
})
}
}