VueJS - Transição e Animação
Neste capítulo, discutiremos os recursos de transição e animação disponíveis no VueJS.
Transição
O VueJS fornece várias maneiras de aplicar a transição aos elementos HTML quando eles são adicionados / atualizados no DOM. VueJS tem um componente de transição embutido que precisa ser envolvido em torno do elemento, que precisa de transição.
Sintaxe
<transition name = "nameoftransition">
<div></div>
</transition>
Vamos considerar um exemplo para entender o funcionamento da transição.
Exemplo
<html>
<head>
<title>VueJs Instance</title>
<script type = "text/javascript" src = "js/vue.js"></script>
</head>
<body>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 2s
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0
}
</style>
<div id = "databinding">
<button v-on:click = "show = !show">Click Me</button>
<transition name = "fade">
<p v-show = "show" v-bind:style = "styleobj">Animation Example</p>
</transition>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#databinding',
data: {
show:true,
styleobj :{
fontSize:'30px',
color:'red'
}
},
methods : {
}
});
</script>
</body>
</html>
Existe um botão chamado clickme criado com o qual podemos mudar o valor da variável show de true para false e vice-versa. Existe ump tagque mostra o elemento de texto apenas se a variável for verdadeira. Envolvemos a tag p com o elemento de transição, conforme mostrado no código a seguir.
<transition name = "fade">
<p v-show = "show" v-bind:style = "styleobj">Animation Example</p>
</transition>
O nome da transição é fade. O VueJS fornece algumas classes padrão para transição e as classes são prefixadas com o nome da transição.
A seguir estão algumas classes padrão para transição -
v-enter- Esta classe é chamada inicialmente antes que o elemento seja atualizado / adicionado. É o estado inicial.
v-enter-active- Esta classe é usada para definir a curva de atraso, duração e atenuação para entrar na fase de transição. Este é o estado ativo para todo e a classe está disponível durante toda a fase de entrada.
v-leave - Adicionado quando a transição de saída é acionada, removido.
v-leave-active- Aplicado na fase de saída. Ele é removido quando a transição é concluída. Esta classe é usada para aplicar a curva de atraso, duração e atenuação durante a fase de saída.
Cada uma das classes acima será prefixada com o nome da transição. Demos o nome da transição como fade, portanto, o nome das classes torna-se.fade_enter, .fade_enter_active, .fade_leave, .fade_leave_active.
Eles são definidos no código a seguir.
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 2s
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0
}
</style>
O .fade_enter_active e .fade_leave_active são definidos juntos e aplica uma transição no início e no estágio de saída. A propriedade opacidade é alterada para 0 em 2 segundos.
A duração é definida em .fade_enter_active e .fade_leave_active. O estágio final é definido em .fade_enter, .fade_leave_to.
A exibição no navegador é a seguinte.
Com um clique no botão, o texto desaparecerá em dois segundos.
Após dois segundos, o texto desaparecerá completamente.
Vamos considerar outro exemplo, onde há uma imagem e ela é deslocada no eixo x quando o botão é clicado.
Exemplo
<html>
<head>
<title>VueJs Instance</title>
<script type = "text/javascript" src = "js/vue.js"></script>
</head>
<body>
<style>
.shiftx-enter-active, .shiftx-leave-active {
transition: all 2s ease-in-out;
}
.shiftx-enter, .shiftx-leave-to /* .fade-leave-active below version 2.1.8 */ {
transform : translateX(100px);
}
</style>
<div id = "databinding">
<button v-on:click = "show = !show">Click Me</button>
<transition name = "shiftx">
<p v-show = "show">
<img src = "images/img.jpg" style = "width:100px;height:100px;" />
</p>
</transition>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#databinding',
data: {
show:true
},
methods : {
}
});
</script>
</body>
</html>
O nome da transição é shiftx. Uma propriedade transform é usada para deslocar a imagem no eixo x em 100 px usando o seguinte trecho de código.
<style>
.shiftx-enter-active, .shiftx-leave-active {
transition: all 2s ease-in-out;
}
.shiftx-enter, .shiftx-leave-to /* .fade-leave-active below version 2.1.8 */ {
transform : translateX(100px);
}
</style>
A seguir está a saída.
Com o clique do botão, a imagem será deslocada 100px para a direita, conforme mostrado na imagem a seguir.
Animação
As animações são aplicadas da mesma maneira que a transição é feita. A animação também tem classes que precisam ser declaradas para que o efeito ocorra.
Vamos considerar um exemplo para ver como funciona a animação.
Exemplo
<html>
<head>
<title>VueJs Instance</title>
<script type = "text/javascript" src = "js/vue.js"></script>
</head>
<body>
<style>
.shiftx-enter-active {
animation: shift-in 2s;
}
.shiftx-leave-active {
animation: shift-in 2s reverse;
}
@keyframes shift-in {
0% {transform:rotateX(0deg);}
25% {transform:rotateX(90deg);}
50% {transform:rotateX(120deg);}
75% {transform:rotateX(180deg);}
100% {transform:rotateX(360deg);}
}
</style>
<div id = "databinding">
<button v-on:click = "show = !show">Click Me</button>
<transition name = "shiftx">
<p v-show = "show">
<img src = "images/img.jpg" style = "width:100px;height:100px;" />
</p>
</transition>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#databinding',
data: {
show:true
},
methods : {
}
});
</script>
</body>
</html>
Para aplicar animação, existem classes iguais a transição. No código acima, temos uma imagem incluída na tag p, conforme mostrado no seguinte trecho de código.
<transition name = "shiftx">
<p v-show = "show"><img src = "images/img.jpg" style = "width:100px;height:100px;" /></p>
</transition>
O nome da transição é shiftx. A aula aplicada é a seguinte -
<style>
.shiftx-enter-active {
animation: shift-in 2s;
}
.shiftx-leave-active {
animation: shift-in 2s reverse;
}
@keyframes shift-in {
0% {transform:rotateX(0deg);}
25% {transform:rotateX(90deg);}
50% {transform:rotateX(120deg);}
75% {transform:rotateX(180deg);}
100% {transform:rotateX(360deg);}
}
</style>
A classe é prefixada com o nome da transição, ou seja, shiftx-enter-active e .shiftx-leave-active. A animação é definida com os quadros-chave de 0% a 100%. Há uma transformação definida em cada um dos quadros-chave, conforme mostrado no código a seguir.
@keyframes shift-in {
0% {transform:rotateX(0deg);}
25% {transform:rotateX(90deg);}
50% {transform:rotateX(120deg);}
75% {transform:rotateX(180deg);}
100% {transform:rotateX(360deg);}
}
A seguir está a saída.
Ao clicar no botão, ele gira de 0 a 360 graus e desaparece.
Classes de transição personalizadas
O VueJS fornece uma lista de classes personalizadas, que podem ser adicionadas como atributos ao elemento de transição.
- enter-class
- enter-active-class
- leave-class
- leave-active-class
As classes personalizadas basicamente entram em ação quando queremos usar uma biblioteca CSS externa, como animate.css.
Exemplo
<html>
<head>
<link href = "https://cdn.jsdelivr.net/npm/[email protected]" rel = "stylesheet" type = "text/css">
<script type = "text/javascript" src = "js/vue.js"></script>
</head>
<body>
<div id = "animate" style = "text-align:center">
<button @click = "show = !show"><span style = "font-size:25px;">Animate</span></button>
<transition
name = "custom-classes-transition"
enter-active-class = "animated swing"
leave-active-class = "animated bounceIn">
<p v-if = "show"><span style = "font-size:25px;">Example</span></p>
</transition>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#animate',
data: {
show: true
}
});
</script>
</body>
</html>
Resultado
Resultado
Resultado
Existem duas animações aplicadas no código acima. Um enter-active-class = “swing animado” e outro leave-active-class = ”animado bounceIn”. Estamos usando classes de animação personalizadas para a animação a ser aplicada a partir da biblioteca de terceiros.
Duração da transição explícita
Podemos aplicar transição e animação no elemento usando VueJS. Vue aguarda os eventos transionend e animationend para detectar se a animação ou transição foi concluída.
Às vezes, a transição pode causar atrasos. Nesses casos, podemos aplicar a duração explicitamente como segue.
<transition :duration = "1000"></transition>
<transition :duration = "{ enter: 500, leave: 800 }">...</transition>
Podemos usar a propriedade de duração com um: no elemento de transição, conforme mostrado acima. Caso haja necessidade de especificar a duração separadamente para entrada e saída, isso pode ser feito conforme mostrado no trecho de código acima.
Ganchos de JavaScript
As classes de transição podem ser chamadas como métodos usando eventos JavaScript. Vamos considerar um exemplo para melhor compreensão.
Exemplo
<html>
<head>
<title>VueJs Instance</title>
<script type = "text/javascript" src = "js/vue.js"></script>
</head>
<body>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<div id = "example-4">
<button @click = "show = !show">
<span style = "font-size:25px;">Toggle</span>
</button>
<transition v-on:before-enter = "beforeEnter"
v-on:enter = "enter"
v-on:leave = "leave"
v-bind:css = "false">
<p v-if = "show" style = "font-size:25px;">Animation Example with velocity</p>
</transition>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#example-4',
data: {
show: false
},
methods: {
beforeEnter: function (el) {
el.style.opacity = 0
},
enter: function (el, done) {
Velocity(el, { opacity: 1, fontSize: '25px' }, { duration: 1000 })
Velocity(el, { fontSize: '10px' }, { complete: done })
},
leave: function (el, done) {
Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 1500 })
Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
Velocity(el, {
rotateZ: '45deg',
translateY: '30px',
translateX: '30px',
opacity: 0
}, { complete: done })
}
}
});
</script>
</body>
</html>
Resultado
No exemplo acima, estamos realizando animação usando métodos js no elemento de transição.
Os métodos de transição são aplicados da seguinte forma -
<transition v-on:before-enter = "beforeEnter"
v-on:enter = "enter"
v-on:leave = "leave"
v-bind:css = "false">
<p v-if = "show" style = "font-size:25px;">Animation Example with velocity</p>
</transition>
Há um prefixo adicionado v-one o nome do evento para o qual o método é chamado. Os métodos são definidos na instância Vue da seguinte forma -
methods: {
beforeEnter: function (el) {
el.style.opacity = 0
},
enter: function (el, done) {
Velocity(el, { opacity: 1, fontSize: '25px' }, { duration: 1000 })
Velocity(el, { fontSize: '10px' }, { complete: done })
},
leave: function (el, done) {
Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 1500 })
Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
Velocity(el, {
rotateZ: '45deg',
translateY: '30px',
translateX: '30px',
opacity: 0
}, { complete: done })
}
}
A transição necessária é aplicada em cada um desses métodos. Há uma animação de opacidade aplicada com o clique do botão e também quando a animação é feita. A biblioteca de terceiros é usada para animação.
Há uma propriedade adicionada na transição v-bind: css = "false", que é feito para que Vue entenda que é uma transição JavaScript.
Transição na renderização inicial
Para adicionar animação no início, precisamos adicionar a propriedade 'appear' ao elemento de transição.
Vejamos um exemplo para entender melhor.
Exemplo
<html>
<head>
<link href = "https://cdn.jsdelivr.net/npm/[email protected]" rel = "stylesheet" type = "text/css">
<script type = "text/javascript" src = "js/vue.js"></script>
</head>
<body>
<div id = "animate" style = "text-align:center">
<transition
appear
appear-class = "custom-appear-class"
appear-active-class = "animated bounceIn">
<h1>BounceIn - Animation Example</h1>
</transition>
<transition
appear
appear-class = "custom-appear-class"
appear-active-class = "animated swing">
<h1>Swing - Animation Example</h1>
</transition>
<transition
appear
appear-class = "custom-appear-class"
appear-active-class = "animated rubberBand">
<h1>RubberBand - Animation Example</h1>
</transition>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#animate',
data: {
show: true
}
});
</script>
</body>
</html>
No exemplo acima, usamos três animações diferentes da biblioteca animate.css. Adicionamos aparência ao elemento de transição.
Na execução do código acima, a seguir será a saída no navegador.
Animação em Componentes
Podemos encerrar a transição para os componentes usando o código a seguir. Nós usamos o componente dinâmico aqui.
Exemplo
<html>
<head>
<title>VueJs Instance</title>
<script type = "text/javascript" src = "js/vue.js"></script>
<link href = "https://cdn.jsdelivr.net/npm/[email protected]" rel = "stylesheet" type = "text/css">
</head>
<body>
<div id = "databinding" style = "text-align:center;">
<transition appear
appear-class = "custom-appear-class"
appear-active-class = "animated wobble">
<component v-bind:is = "view"></component>
</transition>
</div>
<script type = "text/javascript">
var vm = new Vue({
el: '#databinding',
data: {
view: 'component1'
},
components: {
'component1': {
template: '<div><span style = "font-
size:25;color:red;">Animation on Components</span></div>'
}
}
});
</script>
</body>
</html>