Transições e Animações no Vue 2

O Vue permite aplicar efeitos de transição durante a manipulação do DOM, como inserção, atualização ou remoção de elementos. Entre as opções disponíveis estão:

  • Aplicação automática de classes para transições e enimações CSS.
  • Integração com bibliotecas de animação CSS de terceiros, como Animate.css.
  • Uso de funções de gancho JavaScript para manipulação direta do DOM.
  • Suporte para bibliotecas de animação JavaScript, como Velocity.js.

O componente <transition> encapsula elementos ou componentes para adicionar transições de entrada/saída em cenários como renderização condicional (v-if), exibição condicional (v-show), componentes dinâmicos ou nós raiz. Ao inserir ou remover elementos dentro do <transition>, o Vue:

  • Detecta automaticamente transições ou animações CSS e aplica classes nos momentos apropriados.
  • Chama funções de gancho JavaScript fornecidas, se existirem.
  • Executa as operações de DOM imediatamente no próximo quadro se nenhuma transição CSS ou gancho JavaScript for encontrado.

Transição de Elemento ou Componente Único

Exemplo básico de transição usando CSS para controlar a visibilidade de um elemento:

<script src="./lib/vue-2.4.0.js"></script>
<style>
  .v-enter,
  .v-leave-to {
    opacity: 0;
    transform: translateX(150px);
  }
  .v-enter-active,
  .v-leave-active {
    transition: all 0.8s ease;
  }
</style>

<div id="aplicativo">
  <input type="button" value="Alternar" @click="visivel = !visivel">
  <transition>
    <h3 v-if="visivel">Isso é um H3</h3>
  </transition>
</div>

<script>
  var vm = new Vue({
    el: '#aplicativo',
    data: {
      visivel: false
    }
  });
</script>

Classes de Transição

Durante a entrada/saída, seis classes são alternadas com o prefixo padrão v-:

  • v-enter: estado inicial antes da inserção.
  • v-enter-active: estado durante a transição de entrada.
  • v-enter-to: estado final após a entrada (versão 2.1.8+).
  • v-leave: estado inicial ao iniciar a saída.
  • v-leave-active: estado durante a transição de saída.
  • v-leave-to: estado final após a saída (versão 2.1.8+).

Para personalizar o prefixo, use o atributo name em <transition>. Por exemplo, <transition name="customizado"> substituirá v- por customizado-.

Transições CSS

Defina diferentes animações de entrada e saída usando classes CSS personalizadas:

<style>
  .animacao-entrada,
  .animacao-saida {
    opacity: 0;
    transform: translateY(70px);
  }
  .animacao-entrada-ativa,
  .animacao-saida-ativa {
    transition: all 0.8s ease;
  }
</style>

<div id="app">
  <transition name="animacao">
    <div v-if="mostrar">Conteúdo animado</div>
  </transition>
</div>

Animações CSS

Enimações CSS funcionam de forma semelhante, mas a classe v-enter não é removida até o evento animationend. Exemplo com um efeito de escala:

<div id="exemplo">
  <button @click="ativo = !ativo">Alternar</button>
  <transition name="escala">
    <p v-if="ativo">Texto com animação de escala</p>
  </transition>
</div>

<script>
  new Vue({
    el: '#exemplo',
    data: { ativo: true }
  });
</script>

<style>
  .escala-enter-ativo {
    animation: entrada-escala 0.5s;
  }
  .escala-leave-ativo {
    animation: entrada-escala 0.5s reverse;
  }
  @keyframes entrada-escala {
    0% { transform: scale(0); }
    50% { transform: scale(1.5); }
    100% { transform: scale(1); }
  }
</style>

Uso com Bibliotecas de Terceiros

Atributos como enter-active-class e leave-active-class permitem integrar com bibliotecas como Animate.css. Use :duration para controlar a duração:

<link rel="stylesheet" href="./lib/animate.css">

<div id="app">
  <transition
    enter-active-class="bounceIn"
    leave-active-class="bounceOut"
    :duration="{ enter: 200, leave: 400 }">
    <h3 v-if="visivel" class="animated">Elemento animado</h3>
  </transition>
</div>

Ganchos JavaScript

Funções de gancho como before-enter e leave permitem controlar animações via JavaScript. Use v-bind:css="false para desativar a detecção CSS:

<transition
  @before-enter="iniciaEntrada"
  @enter="executaEntrada"
  @after-enter="finalizaEntrada">
  <div v-show="bolaVisivel" class="bola"></div>
</transition>

<script>
  methods: {
    iniciaEntrada(el) {
      el.style.transform = "translate(0, 0)";
    },
    executaEntrada(el, done) {
      el.offsetWidth; // Força a atualização
      el.style.transform = "translate(150px, 450px)";
      el.style.transition = 'all 1s ease';
      done();
    },
    finalizaEntrada(el) {
      this.bolaVisivel = !this.bolaVisivel;
    }
  }
</script>

Transição de Listas com transition-group

Para listas renderizadas com v-for, use <transition-group> e defina uma chave única para cada item. O atributo appear aplica a transição no carregamento inicial, e tag especifica o elemento raiz:

<transition-group appear tag="ul">
  <li v-for="(item, idx) in itens" :key="item.id" @click="remover(idx)">
    {{ item.id }} - {{ item.nome }}
  </li>
</transition-group>

<style>
  .v-enter, .v-leave-to { opacity: 0; transform: translateY(80px); }
  .v-enter-active, .v-leave-active { transition: all 0.6s ease; }
  .v-move { transition: all 0.6s ease; }
  .v-leave-active { position: absolute; }
</style>

Transição de Múltiplos Componentes

Use componentes dinâmicos com :is e o atributo mode para controlar a sequência de transição:

<div id="app">
  <a href="#" @click.prevent="componenteAtual = 'login'">Login</a>
  <a href="#" @click.prevent="componenteAtual = 'registro'">Registro</a>
  <transition mode="out-in">
    <component :is="componenteAtual"></component>
  </transition>
</div>

<script>
  Vue.component('login', { template: '<h3>Componente de Login</h3>' });
  Vue.component('registro', { template: '<h3>Componente de Registro</h3>' });

  new Vue({
    el: '#app',
    data: { componenteAtual: 'login' }
  });
</script>

Transição de Múltiplos Elementos

Ao alternar entre elementos com a mesma tag, use v-if/v-else e atributos key distintos para garantir a transição correta:

<transition>
  <button v-if="editando" key="salvar">Salvar</button>
  <button v-else key="editar">Editar</button>
</transition>

<transition>
  <button :key="estado">
    {{ mensagemBotao }}
  </button>
</transition>

Propriedades computadas podem simplificar a lógica, como no exemplo acima, onde mensagemBotao varia com base no estado do documento.

Tags: vue2 transicoes Animações CSS javascript

Publicado em 7-18 12:41