Guia
Essenciais
- Instalação
- Introdução
- A Instância Vue
- Sintaxe de Templates
- Dados Computados e Observadores
- Interligações de Classe e Estilo
- Renderização Condicional
- Renderização de Listas
- Manipulação de Eventos
- Interligações em Formulários
- Básico sobre Componentes
Componentes em Detalhes
- Registro de Componentes
- Propriedades
- Eventos Personalizados
- Slots
- Dinâmicos & Assíncronos
- Lidando com Casos Extremos
Transições & Animações
- Transições de Visibilidade e Listas
- Transições de Estado
Reuso & Composição
- Mixins
- Diretivas Personalizadas
- Funções de Renderização & JSX
- Plugins
- Filtros
Ferramentas
- Componentes Single-File
- Testes Unitários
- Testing
- Suporte ao TypeScript
- Publicando em Produção
Escalonando
- Roteamento
- Gerenciamento de Estado
- Renderizando no Lado do Servidor
- Segurança
Internamente
- Reatividade em Profundidade
Migração
- Migração do Vue 1.x
- Migração do Vue Router 0.7.x
- Migração do Vuex 0.6.x para 1.0
Diversos
- Comparação com Outros Frameworks
- Junte-se à Comunidade Vue.js!
- Conheça a Equipe
Você está navegando a documentação da v2.x e anterior. Para a v3.x, clique aqui.
Transições de Visibilidade e Listas
Visão Geral
Vue disponibiliza uma variedade de maneiras para a aplicação de efeitos de transição quando itens são inseridos, atualizados, ou removidos do DOM. Isto inclui ferramentas para:
- aplicar automaticamente as classes para as transições e animações CSS
- integrar bibliotecas de terceiros para animação CSS, como Animate.css
- utilizar JavaScript para manipular diretamente o DOM durante gatilhos de transição
- integrar bibliotecas de animação JavaScript de terceiros, como o Velocity.js
Nesta página, nós falaremos apenas sobre transições de entrada, saída, e de lista, mas você pode ver a próxima seção para transição de estados.
Transição Individual de Elementos
Vue disponibiliza um componente encapsulador (wrapper) chamado transition
, permitindo que você adicione transição de entrada/saída para qualquer elemento ou componente dentro do seguinte contexto:
- Renderização condicional (usando
v-if
) - Exibição condicional (usando
v-show
) - Componentes dinâmicos
- Componentes de nós de raiz
Aqui está um exemplo destes em ação:
<div id="demo">
<button v-on:click="show = !show">
Alternar
</button>
<transition name="fade">
<p v-if="show">olá</p>
</transition>
</div>
new Vue({
el: '#demo',
data: {
show: true
}
})
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active em versões anteriores a 2.1.8 */ {
opacity: 0;
}
olá
Quando um elemento dentro de um componente transition
é inserido ou removido, eis o que acontece:
Vue irá automaticamente procurar se o elemento alvo tem transições CSS ou animações aplicadas. Caso positivo, as classes de transições CSS serão adicionadas/removidas nos momentos apropriados.
Se o componente de transição fornece Gatilhos por JavaScript, estes gatilhos serão invocados nos momentos apropriados.
Se nenhuma transição/animação CSS é detectada e nenhum JavaScript hook é fornecido, as operações de inserção e/ou remoção no DOM serão executadas imediatamente no próximo frame (Nota: isto é um frame de animação do browser, diferente do conceito de
nextTick
do Vue).
Classes de Transição
Existem seis classes aplicadas para transição de entrada/saída.
v-enter
: Inicia o estado de entrada. Aplicada antes do elemento ser inserido, removida depois de um frame.v-enter-active
: Ativa e termina o estado de entrada. Aplicada antes do elemento ser inserido, removida quando a transição/animação termina.v-enter-to
: Disponível apenas nas versões 2.1.8+. Estado final de entrada. Adicionada um frame após o elemento ser inserido (ao mesmo tempo quev-enter
é removida), e removida quando a transição/animação termina.v-leave
: Ativa o estado de saída. Aplicada quando a transição de saída é acionada, removida depois de um frame.v-leave-active
: Estado ativo de saída. Aplicada durante toda a fase de saída. Adicionada imediatamente quando a transição de saída é disparada, removida quando a transição/animação termina. Esta classe pode ser usada para definir a duração, atraso e a curva da transição de saída.v-leave-to
: Disponível apenas nas versões 2.1.8+. Estado final da saída. Adicionada um frame após a transição de saída ser disparada (ao mesmo tempo quev-leave
é removida), e removida quando a transição/animação termina.
Cada uma destas classes será prefixada com o nome da transição. Aqui, o prefixo v-
é padrão quando você utiliza o elemento <transition>
sem nome. Se você, por exemplo, utilizar <transition name="my-transition">
a classe v-enter
seria, no entanto, my-transition-enter
.
v-enter-active
e v-leave-active
permitem especificar diferentes progressões de curvas para transição de entrada/saída, das quais você verá um exemplo na seção seguinte.
Transição CSS
Um dos tipos mais comuns de transição se utiliza de transições CSS. Segue um exemplo:
<div id="exemplo-1">
<button @click="show = !show">
Alterna renderização
</button>
<transition name="slide-fade">
<p v-if="show">olá</p>
</transition>
</div>
new Vue({
el: '#exemplo-1',
data: {
show: true
}
})
/* Animações de entrada e saída podem utilizar diferentes */
/* funções de duração e de tempo. */
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active em versões anteriores a 2.1.8 */ {
transform: translateX(10px);
opacity: 0;
}
olá
Animações CSS
Animações CSS são aplicadas da mesma forma que as transições CSS, sendo que a diferença é que v-enter
não é removida imediatamente após o elemento ser inserido, mas sim no evento animationend
.
Eis um exemplo, omitindo as regras de prefixo CSS, por uma questão de brevidade:
<div id="exemplo-2">
<button @click="show = !show">Alternar visualização</button>
<transition name="bounce">
<p v-if="show">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus.</p>
</transition>
</div>
new Vue({
el: '#exemplo-2',
data: {
show: true
}
})
.bounce-enter-active {
animation: bounce-in .5s;
}
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus.
Classes de Transição Personalizadas
Você também pode especificar uma classe de transição personalizada fornecendo os seguintes atributos:
enter-class
enter-active-class
enter-to-class
(2.1.8+)leave-class
leave-active-class
leave-to-class
(2.1.8+)
Estes irão substituir os nomes convencionais das classes. Isso é especialmente útil quando você quer combinar o sistema de transição do Vue com outra biblioteca CSS de animação já existente, como Animate.css.
Eis um exemplo:
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<div id="example-3">
<button @click="show = !show">
Alterna renderização
</button>
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<p v-if="show">olá</p>
</transition>
</div>
new Vue({
el: '#exemplo-3',
data: {
show: true
}
})
olá
Usando Transição e Animação juntos
Vue precisa escutar eventos para que consiga saber quando uma transição acabou. Os eventos podem ser transitionend
ou animationend
, dependendo do tipo de regra CSS aplicada. Se você utilizar apenas uma ou outra, Vue detectará automaticamente o tipo correto.
No entanto, em alguns casos, você poderá usar os dois tipos em um só elemento, como por exemplo, ter uma animação CSS que será acionada pelo Vue, juntamente com um efeito de transição CSS acionado pelo hover. Nestes casos, você terá que declarar explicitamente o tipo de evento que você gostaria que o Vue utilizasse em um atributo type
, com o valor animation
ou transition
.
Duração Explícita de Transição
Novo em 2.2.0+
Na maioria dos casos, Vue consegue automaticamente detectar quando a animação terminou. Por padrão, Vue aguarda pelo primeiro evento transitionend
ou animationend
no elemento raiz da transição. Porém, nem sempre isso é o desejado: nós podemos, por exemplo, ter uma transição coreografada onde alguns dos elementos filhos tem tempos diferentes em relação ao elemento raiz.
Nestes casos você pode especificar uma duração (em milissegundos) usando a propriedade duration
no componente <transition>
:
<transition :duration="1000">...</transition>
Você também pode especificar valores separados para a duração de entrada e saída:
<transition :duration="{ enter: 500, leave: 800 }">...</transition>
Gatilhos por JavaScript
Você também pode definir os gatilhos (em inglês, JavaScript hooks) nos atributos:
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
<!-- ... -->
</transition>
// ...
methods: {
// --------
// ENTRANDO
// --------
beforeEnter: function (el) {
// ...
},
// o callback de finalização é opcional quando
// utilizado em combinação com CSS
enter: function (el, done) {
// ...
done()
},
afterEnter: function (el) {
// ...
},
enterCancelled: function (el) {
// ...
},
// --------
// SAINDO
// --------
beforeLeave: function (el) {
// ...
},
// o callback de finalização é opcional quando
// utilizado em combinação com CSS
leave: function (el, done) {
// ...
done()
},
afterLeave: function (el) {
// ...
},
// leaveCancelled apenas disponível com v-show
leaveCancelled: function (el) {
// ...
}
}
Estes gatilhos podem ser utilizados em combinação com transição/animação CSS ou sozinhos.
Ao utilizar transições puramente JavaScript, os callbacks done
para os gatilhos enter
e o leave
são obrigatórios. Caso contrário, serão invocados de forma síncrona e a transição terá um fim imediato.
Ao utilizar transições puramente JavaScript, é uma boa ideia adicionar explicitamente v-bind:css="false"
para que o Vue possa pular a detecção de CSS. Isso também previne que regras CSS interfiram acidentalmente na transição.
Agora vamos mergulhar em um exemplo. Segue uma transição JavaScript com Velocity.js:
<!--
Velocity funciona muito parecido com o jQuery.animate e é uma excelente opção para animações JavaScript
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<div id="exemplo-4">
<button @click="show = !show">
Alternar
</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
v-bind:css="false"
>
<p v-if="show">
Demo
</p>
</transition>
</div>
new Vue({
el: '#exemplo-4',
data: {
show: false
},
methods: {
beforeEnter: function (el) {
el.style.opacity = 0
el.style.transformOrigin = 'left'
},
enter: function (el, done) {
Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
Velocity(el, { fontSize: '1em' }, { complete: done })
},
leave: function (el, done) {
Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
Velocity(el, {
rotateZ: '45deg',
translateY: '30px',
translateX: '30px',
opacity: 0
}, { complete: done })
}
}
})
Demo
Transição na Renderização Inicial
Se você quiser aplicar a transição na renderização inicial de um nó, basta adicionar o atributo appear
:
<transition appear>
<!-- ... -->
</transition>
Por padrão, isso utilizará a transição especificada para entrada e saída. Se você desejar, poderá ainda especificar classes CSS específicas:
<transition
appear
appear-class="custom-appear-class"
appear-to-class="custom-appear-to-class" (2.1.8+)
appear-active-class="custom-appear-active-class"
>
<!-- ... -->
</transition>
e ganchos JavaScript personalizados
<transition
appear
v-on:before-appear="customBeforeAppearHook"
v-on:appear="customAppearHook"
v-on:after-appear="customAfterAppearHook"
v-on:appear-cancelled="customAppearCancelledHook"
>
<!-- ... -->
</transition>
No exemplo acima, ambos atributo appear
ou gatilho v-on:appear
farão com que apareça uma transição.
Transição entre Elementos
Nós discutiremos sobre transição entre Componentes em breve, mas você pode realizar transição entre elementos puros utilizando v-if
/v-else
. Uma das transições de dois elementos mais comum é entre um recipiente de lista e uma mensagem descrevendo uma lista vazia:
<transition>
<table v-if="items.length > 0">
<!-- ... -->
</table>
<p v-else>Desculpe, nenhum item encontrado.</p>
</transition>
Isso funciona bem, mas existe uma ressalva à qual precisamos estar atentos:
Quando alternamos entre elementos com a mesma tag, você precisa informar o Vue que eles são elementos distintos por meio do atributo único key
. Caso contrário, o compilador do Vue irá substituir apenas o conteúdo do elemento por questões de eficiência. Mesmo quando tecnicamente não necessário, é considerado uma boa prática sempre utilizar o atributo key
nos múltiplos itens dentro de um componente <transition>
Por exemplo:
<transition>
<button v-if="isEditing" key="save">
Salvar
</button>
<button v-else key="edit">
Editar
</button>
</transition>
Nestes casos você também poderá usar o atributo key
para realizar transições entre diferentes estados de um mesmo elemento. Em vez de utilizar v-if
e v-else
, o exemplo a seguir pode ser reescrito da seguinte forma:
<transition>
<button v-bind:key="isEditing">
{{ isEditing ? 'Salvar' : 'Editar' }}
</button>
</transition>
Também é possível realizar transições entre qualquer número de elementos, utilizando múltiplos v-if
ou vinculando um elemento único a uma propriedade dinâmica. Por exemplo:
<transition>
<button v-if="docState === 'saved'" key="saved">
Editar
</button>
<button v-if="docState === 'edited'" key="edited">
Salvar
</button>
<button v-if="docState === 'editing'" key="editing">
Cancelar
</button>
</transition>
Que também pode ser escrito como:
<transition>
<button v-bind:key="docState">
{{ buttonMessage }}
</button>
</transition>
// ...
computed: {
buttonMessage: function () {
switch (this.docState) {
case 'saved': return 'Editar'
case 'edited': return 'Salvar'
case 'editing': return 'Cancelar'
}
}
}
Modos de Transição
No entanto, ainda temos um problema. Tente clicar no botão abaixo:
Por estarem transitando entre o botão “ligar” e o botão “desligar”, ambos os botões são renderizados - uma transição sai enquanto a outra transição entra. Este é o comportamento padrão do <transition>
- entrada e saída acontecem simultaneamente.
Às vezes isso funciona perfeitamente, como quando realizamos transições de itens que são absolutamente posicionados no topo uns dos outros:
E também utilizar translate para que se pareça com uma transição slide:
No entanto, transições de entrada e saída simultâneas nem sempre são desejadas. Neste caso, o Vue oferece alguns modos de transição alternativos:
in-out
: Novo elemento realiza a transição de entrada primeiro; quando completada, o elemento atual realiza a transição de saída.out-in
: Elemento atual realiza a transição de saída primeiro; quando completada, o novo elemento realiza a transição de entrada.
Agora vamos atualizar a transição para os nossos botões ligar/desligar com out-in
:
<transition name="fade" mode="out-in">
<!-- ... os botões ... -->
</transition>
Com a adição de um atributo, corrigimos nossa transição original sem ter de adicionar qualquer estilo especial.
O modo in-out
não é utilizado com frequência, mas às vezes pode ser útil para um efeito de transição ligeiramente diferente. Vamos tentar combiná-lo com a transição slide-fade em que trabalhamos anteriormente:
Bem legal, certo?
Transições entre Componentes
Transições entre componentes são ainda mais simples - nem precisamos do atributo key
. Em vez disso, encapsulamos em um componente dinâmico:
<transition name="component-fade" mode="out-in">
<component v-bind:is="view"></component>
</transition>
new Vue({
el: '#transition-components-demo',
data: {
view: 'v-a'
},
components: {
'v-a': {
template: '<div>Component A</div>'
},
'v-b': {
template: '<div>Component B</div>'
}
}
})
.component-fade-enter-active, .component-fade-leave-active {
transition: opacity .3s ease;
}
.component-fade-enter, .component-fade-leave-to
/* .component-fade-leave-active em versões anteriores a 2.1.8 */ {
opacity: 0;
}
Transições em Listas
Até agora, temos transições para:
- Nós individuais
- Múltiplos nós onde apenas um é renderizado por vez
Então, que tal ter uma lista de itens e renderizá-los simultaneamente com o v-for
, por exemplo? Neste caso, utilizaremos o componente <transition-group>
. Antes de entrarmos em um exemplo, existem algumas coisas que é importante saber sobre este componente:
- Diferentemente do
<transition>
, ele renderiza um elemento por padrão: o<span>
. Você pode mudar o elemento que é renderizado com o atributotag
. - Modos de Transição não estão disponíveis, pois não estamos mais alternando entre elementos mutuamente exclusivos.
- Elementos dentro sempre requerem um atributo
key
único. - Classes de transição CSS serão aplicadas a elementos internos e não ao grupo/container em si.
Transição de Entrada/Saída de Lista
Agora vamos analisar um exemplo, transitando entrada e saída com as mesmas classes CSS que usamos anteriormente:
<div id="list-demo" class="demo">
<button v-on:click="add">Adicionar</button>
<button v-on:click="remove">Remover</button>
<transition-group name="list" tag="p">
<span v-for="item in items" v-bind:key="item" class="list-item">
{{ item }}
</span>
</transition-group>
</div>
new Vue({
el: '#list-demo',
data: {
items: [1,2,3,4,5,6,7,8,9],
nextNum: 10
},
methods: {
randomIndex: function () {
return Math.floor(Math.random() * this.items.length)
},
add: function () {
this.items.splice(this.randomIndex(), 0, this.nextNum++)
},
remove: function () {
this.items.splice(this.randomIndex(), 1)
},
}
})
.list-item {
display: inline-block;
margin-right: 10px;
}
.list-enter-active, .list-leave-active {
transition: all 1s;
}
.list-enter, .list-leave-to /* .list-leave-active em versões anteriores a 2.1.8 */ {
opacity: 0;
transform: translateY(30px);
}
Há um problema com este exemplo. Quando você adiciona ou remove um item, aqueles em torno dele se encaixam instantaneamente ao invés de fazer a transição suavemente. Nós iremos corrigir isto mais tarde.
Transições de Movimento de Lista
O componente <transition-group>
tem outro truque na manga. Ele não só tem animação de entrada e saída, como também na mudança de posição. O único conceito novo que você precisa saber para usar este recurso é a adição de da classe v-move
, a qual é inserida quando os itens estão mudando suas posições. Assim como outras classes, elas serão prefixadas com o valor fornecido pelo atributo name
e você poderá especificar manualmente uma classe com o atributo move-class
.
Esta classe é útil para especificar o tempo de transição ou a suavidade da curva, como você pode ver adiante:
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
<div id="flip-list-demo" class="demo">
<button v-on:click="shuffle">Misturar</button>
<transition-group name="flip-list" tag="ul">
<li v-for="item in items" v-bind:key="item">
{{ item }}
</li>
</transition-group>
</div>
new Vue({
el: '#flip-list-demo',
data: {
items: [1,2,3,4,5,6,7,8,9]
},
methods: {
shuffle: function () {
this.items = _.shuffle(this.items)
}
}
})
.flip-list-move {
transition: transform 1s;
}
Isto pode parecer mágica, mas internamente Vue está aplicando uma técnica de animação chamada FLIP para suavemente transitar elementos da posição antiga para a posição nova utilizando transformações CSS.
Nós podemos combinar esta técnica com a nossa implementação anterior para animar qualquer mudança na nossa lista!
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
<div id="list-complete-demo" class="demo">
<button v-on:click="shuffle">Misturar</button>
<button v-on:click="add">Adicionar</button>
<button v-on:click="remove">Remover</button>
<transition-group name="list-complete" tag="p">
<span
v-for="item in items"
v-bind:key="item"
class="list-complete-item"
>
{{ item }}
</span>
</transition-group>
</div>
new Vue({
el: '#list-complete-demo',
data: {
items: [1,2,3,4,5,6,7,8,9],
nextNum: 10
},
methods: {
randomIndex: function () {
return Math.floor(Math.random() * this.items.length)
},
add: function () {
this.items.splice(this.randomIndex(), 0, this.nextNum++)
},
remove: function () {
this.items.splice(this.randomIndex(), 1)
},
shuffle: function () {
this.items = _.shuffle(this.items)
}
}
})
.list-complete-item {
transition: all 1s;
display: inline-block;
margin-right: 10px;
}
.list-complete-enter, .list-complete-leave-to
/* .list-complete-leave-active em versões anteriores a 2.1.8 */ {
opacity: 0;
transform: translateY(30px);
}
.list-complete-leave-active {
position: absolute;
}
É importante notar que as transições FLIP não funcionam com elementos display: inline
. Como alternativa, você pode usar display: inline-block
ou colocar os elementos dentro de um contexto flex.
Estas animações FLIP também não são limitadas a um único eixo. Itens em uma grade multidimensional também podem ser transitados:
Clique no botão misturar até ganhar.
Escalonamento de Transições de Lista
Ao comunicar com transições JavaScript por meio de atributos de dados, também é possível escalonar as transições em uma lista:
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<div id="staggered-list-demo">
<input v-model="query">
<transition-group
name="staggered-fade"
tag="ul"
v-bind:css="false"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
>
<li
v-for="(item, index) in computedList"
v-bind:key="item.msg"
v-bind:data-index="index"
>{{ item.msg }}</li>
</transition-group>
</div>
new Vue({
el: '#staggered-list-demo',
data: {
query: '',
list: [
{ msg: 'Bruce Lee' },
{ msg: 'Jackie Chan' },
{ msg: 'Chuck Norris' },
{ msg: 'Jet Li' },
{ msg: 'Kung Fury' }
]
},
computed: {
computedList: function () {
var vm = this
return this.list.filter(function (item) {
return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1
})
}
},
methods: {
beforeEnter: function (el) {
el.style.opacity = 0
el.style.height = 0
},
enter: function (el, done) {
var delay = el.dataset.index * 150
setTimeout(function () {
Velocity(
el,
{ opacity: 1, height: '1.6em' },
{ complete: done }
)
}, delay)
},
leave: function (el, done) {
var delay = el.dataset.index * 150
setTimeout(function () {
Velocity(
el,
{ opacity: 0, height: 0 },
{ complete: done }
)
}, delay)
}
}
})
Transições Reutilizáveis
Transições podem ser reutilizadas por meio do sistema de componentes do Vue. Para criar uma transição reutilizável, tudo o que você precisa fazer é inserir um componente <transition>
ou <transition-group>
em sua raiz, e então adicionar qualquer componente filho dentro do componente de transição.
Eis um exemplo utilizando um modelo de componente:
Vue.component('my-special-transition', {
template: '\
<transition\
name="very-special-transition"\
mode="out-in"\
v-on:before-enter="beforeEnter"\
v-on:after-enter="afterEnter"\
>\
<slot></slot>\
</transition>\
',
methods: {
beforeEnter: function (el) {
// ...
},
afterEnter: function (el) {
// ...
}
}
})
E componentes funcionais são especialmente bem adequados para esta tarefa:
Vue.component('my-special-transition', {
functional: true,
render: function (createElement, context) {
var data = {
props: {
name: 'very-special-transition',
mode: 'out-in'
},
on: {
beforeEnter: function (el) {
// ...
},
afterEnter: function (el) {
// ...
}
}
}
return createElement('transition', data, context.children)
}
})
Transições Dinâmicas
Sim, até as transições no Vue são orientadas a dados (data-driven)! O exemplo mais básico de uma transição dinâmica vincula o atributo name
a uma propriedade dinâmica.
<transition v-bind:name="transitionName">
<!-- ... -->
</transition>
Isto pode ser útil quando você tiver definido transições/animações CSS usando as convenções de classes de transição do Vue e quiser alternar entre elas.
No entanto, qualquer atributo de transição pode ser vinculado dinamicamente. Não apenas atributos: como gatilhos de eventos são métodos, possuem acesso a qualquer dado no contexto. Isto significa que suas transições JavaScript podem se comportar de forma diferente dependendo do estado de seu componente.
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<div id="dynamic-fade-demo" class="demo">
Fade In: <input type="range" v-model="fadeInDuration" min="0" v-bind:max="maxFadeDuration">
Fade Out: <input type="range" v-model="fadeOutDuration" min="0" v-bind:max="maxFadeDuration">
<transition
v-bind:css="false"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
>
<p v-if="show">olá</p>
</transition>
<button
v-if="stop"
v-on:click="stop = false; show = false"
>Começar a animar</button>
<button
v-else
v-on:click="stop = true"
>Pare!</button>
</div>
new Vue({
el: '#dynamic-fade-demo',
data: {
show: true,
fadeInDuration: 1000,
fadeOutDuration: 1000,
maxFadeDuration: 1500,
stop: true
},
mounted: function () {
this.show = false
},
methods: {
beforeEnter: function (el) {
el.style.opacity = 0
},
enter: function (el, done) {
var vm = this
Velocity(el,
{ opacity: 1 },
{
duration: this.fadeInDuration,
complete: function () {
done()
if (!vm.stop) vm.show = false
}
}
)
},
leave: function (el, done) {
var vm = this
Velocity(el,
{ opacity: 0 },
{
duration: this.fadeOutDuration,
complete: function () {
done()
vm.show = true
}
}
)
}
}
})
olá
Finalmente, a última forma para a criação de transições dinâmicas é por meio de componentes que aceitam que suas props
possam mudar a natureza da transição a ser utilizada. Pode parecer clichê, mas o único limite é sua imaginação.