Vue.js: Transições e Animações

Última atualização: 2026-08-26

As transições e animações tornam seu aplicativo Vue mais dinâmico — transições suaves à medida que os elementos entram ou saem da área de exibição e um reajuste elegante à medida que as listas mudam. O Vue inclui os componentes <Transition> e <TransitionGroup>, que funcionam com nomes de classes CSS ou hooks de JavaScript para obter vários efeitos de animação.

Dominar as animações de transição é fundamental para melhorar a experiência do usuário — boas animações fazem com que um aplicativo pareça “fluido, ágil e profissional”.

1. O que você vai aprender


2. O incômodo de um botão físico para “mudar de aba”

(1) Problema: Componentes desaparecem ou aparecem repentinamente; a interface do usuário pisca

O painel de administração do Alice tinha um seletor de abas:

VUE
<!-- ❌ The "Broken" Version:v-if Sudden Switch -->
<template>
  <button @click="currentTab = 'home'">Home</button>
  <button @click="currentTab = 'profile'">Profile</button>
  
  <div v-if="currentTab === 'home'">Home Content</div>
  <div v-else-if="currentTab === 'profile'">Profile Content</div>
</template>

Experiência do usuário:

(2) Solução para transições no Vue: 1 tag, 6 classes

VUE
<!-- ✅ Correct Version:Smooth Transition -->
<template>
  <button @click="currentTab = 'home'">Home</button>
  <button @click="currentTab = 'profile'">Profile</button>
  
  <Transition name="fade" mode="out-in">
    <div v-if="currentTab === 'home'" key="home">Home Content</div>
    <div v-else-if="currentTab === 'profile'" key="profile">Profile Content</div>
  </Transition>
</template>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
</style>

Experiência do usuário:

(3) Receita

Após adicionar as transições:


3. Transição: Elemento Único

(1) Uso básico

VUE
<template>
  <button @click="show = !show">Toggle</button>
  
  <Transition name="fade">
    <p v-if="show">Hello Vue</p>
  </Transition>
</template>

<style>
/* 6 CSS classes, Vue Auto-add/Remove */
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s ease;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
</style>

(2) Uma explicação detalhada sobre 6 classes CSS

Classe Condição de acionamento Finalidade
v-enter-from Antes da inserção do elemento Estado inicial
v-enter-active Todo o processo de inserção de elementos Processo de transição
v-enter-to Após inserir um elemento Estado final
v-leave-from Antes de o elemento sair Estado inicial
v-leave-active O elemento sai de todo o processo Processo de transição
v-leave-to Depois que o elemento sai Estado final

(3) Convenções de nomenclatura

VUE
<!-- v-bind:name="fade" → 6 classes are .fade-xxx -->
<Transition name="fade">...</Transition>

<!-- Don't write name → Default v-xxx (6 classes are .v-xxx) -->
<Transition>...</Transition>

<!-- News name -->
<Transition :name="transitionName">...</Transition>

(4) 3 modos

VUE
<!-- 1. Default Mode:Entry and exit occur simultaneously(Overlap) -->
<Transition name="fade">
  <div v-if="show">Content</div>
</Transition>

<!-- 2. out-in:Leave first, then enter(Recommendations,Avoid Overlapping) -->
<Transition name="fade" mode="out-in">
  <div v-if="show">Content</div>
</Transition>

<!-- 3. in-out:Enter first, then leave(Rare) -->
<Transition name="fade" mode="in-out">
  <div v-if="show">Content</div>
</Transition>

4. 5 tipos de animações CSS

(1) Fade In e Fade Out (os mais comuns)

CSS
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}

(2) Deslizamento

CSS
.slide-enter-active, .slide-leave-active {
  transition: transform 0.3s;
}
.slide-enter-from {
  transform: translateX(-100%);
}
.slide-leave-to {
  transform: translateX(100%);
}

(3) Zoom

CSS
.scale-enter-active, .scale-leave-active {
  transition: transform 0.3s;
}
.scale-enter-from, .scale-leave-to {
  transform: scale(0);
}

(4) Rotação

CSS
.rotate-enter-active {
  transition: transform 1s;
}
.rotate-enter-from {
  transform: rotate(0deg);
}
.rotate-leave-active {
  animation: bounce 0.5s;
}
@keyframes bounce {
  0% { transform: scale(0); }
  50% { transform: scale(1.2); }
  100% { transform: scale(1); }
}

(5) Animação composta

CSS
.combo-enter-active, .combo-leave-active {
  transition: all 0.3s;
}
.combo-enter-from {
  opacity: 0;
  transform: translateX(-50px) scale(0.8);
}
.combo-leave-to {
  opacity: 0;
  transform: translateX(50px) scale(0.8);
}

5. Animações de transição em listas de grupos

(1) Uso básico

VUE
<template>
  <button @click="add">Add</button>
  
  <TransitionGroup name="list" tag="ul">
    <li v-for="item in items" :key="item.id">
      {{ item.name }}
      <button @click="remove(item.id)">×</button>
    </li>
  </TransitionGroup>
</template>

<script setup>
import { ref } from 'vue'
const items = ref([
  { id: 1, name: 'Apple' },
  { id: 2, name: 'Banana' }
])

function add() {
  const id = Date.now()
  items.value.push({ id, name: `Item ${id}` })
}

function remove(id) {
  items.value = items.value.filter(i => i.id !== id)
}
</script>

<style>
/* 6 classes, However, for list items, enter/leave/move */
.list-enter-active, .list-leave-active {
  transition: all 0.5s;
}
.list-enter-from, .list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}
.list-leave-active {
  position: absolute;  /* Remove from the document flow when leaving */
}
/* Animation when list items move */
.list-move {
  transition: transform 0.5s;
}
</style>

(2) Ponto-chave: .list-move

CSS
/* When the position of a list item changes(As sorted),Apply Automatically .list-move */
.list-move {
  transition: transform 0.5s;
}

(3) 5 principais cenários de animação de listas

Cena Animação
Adicionar item Entrada com efeito de desvanecimento + deslizamento para baixo
Excluir item Desaparecer gradualmente + deslizar para a esquerda
Ordenar Mover suavemente para a nova posição
Filtro Desvanecimento para itens que estão sendo removidos, transição suave para itens que estão sendo mantidos
Arrastar Seguir o mouse em tempo real

6. Hooks do JavaScript

(1) 8 ganchos de JavaScript

VUE
<template>
  <Transition
    @before-enter="beforeEnter"
    @enter="enter"
    @after-enter="afterEnter"
    @before-leave="beforeLeave"
    @leave="leave"
    @after-leave="afterLeave"
    :css="false"  <!-- Disable CSS class -->
  >
    <p v-if="show">Hello</p>
  </Transition>
</template>

<script setup>
import gsap from 'gsap'

function beforeEnter(el) {
  console.log('Before enter:', el)
}

function enter(el, done) {
  gsap.to(el, {
    opacity: 1,
    y: 0,
    duration: 0.5,
    onComplete: done  // Notification Complete
  })
}

function afterEnter(el) {
  console.log('After enter:', el)
}

// leave / beforeLeave / afterLeave Similar
</script>

(2) Integração com o GSAP (recomendado)

BASH
npm install gsap
VUE
<template>
  <Transition :css="false" @enter="onEnter" @leave="onLeave">
    <p v-if="show">Hello GSAP</p>
  </Transition>
</template>

<script setup>
import gsap from 'gsap'

function onEnter(el, done) {
  gsap.fromTo(el, 
    { opacity: 0, y: 50 },
    { opacity: 1, y: 0, duration: 0.5, onComplete: done }
  )
}

function onLeave(el, done) {
  gsap.to(el, { opacity: 0, y: -50, duration: 0.3, onComplete: done })
}
</script>

7. Bibliotecas de animação de terceiros

(1) Integração com o Animate.css

BASH
npm install animate.css
JS
// main.js
import 'animate.css'
VUE
<template>
  <Transition
    enter-active-class="animate__animated animate__fadeIn"
    leave-active-class="animate__animated animate__fadeOut"
  >
    <p v-if="show">Hello</p>
  </Transition>
</template>

(2) @vueuse/motion

BASH
npm install @vueuse/motion
JS
// main.js
import { MotionPlugin } from '@vueuse/motion'
app.use(MotionPlugin)
VUE
<template>
  <div v-motion :initial="{ opacity: 0, y: 50 }" :enter="{ opacity: 1, y: 0 }">
    Fade in from below
  </div>
</template>

(3) Casos de uso recomendados para o GSAP

Biblioteca Classificação Indicado para
Animações CSS ⭐⭐⭐⭐⭐ Transições simples, efeitos de desvanecimento
Animate.css ⭐⭐⭐⭐ Uma ampla variedade de animações predefinidas
@vueuse/motion ⭐⭐⭐⭐ Declarativo, integra-se bem com o Vue
GSAP ⭐⭐⭐⭐⭐ Linhas do tempo complexas, animações baseadas na física

8. Exemplos completos: 5 principais cenários de transição

▶ Exemplo: 1. 5 tipos de animações CSS

CSS
/* 1. Fade In, Fade Out */
.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
.fade-enter-from, .fade-leave-to { opacity: 0; }

/* 2. Slide */
.slide-enter-active, .slide-leave-active { transition: transform 0.3s; }
.slide-enter-from { transform: translateX(-100%); }
.slide-leave-to { transform: translateX(100%); }

/* 3. Zoom */
.scale-enter-active, .scale-leave-active { transition: transform 0.3s; }
.scale-enter-from, .scale-leave-to { transform: scale(0); }

/* 4. Rotation */
.rotate-enter-active { transition: transform 1s; }
.rotate-enter-from { transform: rotate(0deg); }
.rotate-leave-active { animation: spin 0.5s; }

/* 5. Combination */
.combo-enter-active, .combo-leave-active { transition: all 0.3s; }
.combo-enter-from { opacity: 0; transform: translateX(-50px) scale(0.8); }
▶ Experimente

▶ Exemplo: 2. Explicação detalhada de 6 classes CSS

Classe Gatilho
.fade-enter-from Antes de inserir um elemento
.fade-enter-active Processo de inserção de elementos
.fade-enter-to Após inserir o elemento
.fade-leave-from Antes que o Elemento se vá
.fade-leave-active Processo de saída de elementos
.fade-leave-to Depois que o Elemento Partiu

▶ Exemplo: 3. Animação de lista com TransitionGroup

VUE
<TransitionGroup name="list" tag="ul">
  <li v-for="item in items" :key="item.id">
    {{ item.name }}
  </li>
</TransitionGroup>

<style>
.list-enter-active, .list-leave-active {
  transition: all 0.5s;
}
.list-move { transition: transform 0.5s; }
</style>
▶ Experimente

▶ Exemplo: 4. 5 Principais bibliotecas de animação de terceiros

Biblioteca Comando Aplicável
CSS Nenhum (integrado) Simples
Animate.css npm i animate.css Animações predefinidas
@vueuse/motion npm i @vueuse/motion Declarativo
GSAP npm i gsap Linha do tempo complexa
Motion One npm i motion Animação leve para a web

▶ Exemplo: 5. Referência rápida para 5 erros comuns

Erro Sintoma Solução
A transição não é aplicada O elemento desaparece imediatamente Adicionar o wrapper <Transition> + v-if
v-for sem animação sem transições entre os itens da lista usando <TransitionGroup>
Não há animação ao classificar Movimentos irregulares Adicionar a classe .list-move
Comutação simultânea entre vários componentes Sobreposição Adicionar key para distinguir + mode="out-in"
As animações CSS são muito rápidas/muito lentas Experiência do usuário insatisfatória Ajuste a duração da transição para 0,2–0,5 s

▶ Exemplo: 6. 5 Cenários práticos

Cena Animação
Alternância de abas fade + de fora para dentro
Caixa de diálogo modal ampliar + esmaecer
Adicionar/Remover da lista Animação da lista
Mudança de rota fade + slide
Notificação pop-up desliza do topo + fechamento automático

❓ Perguntas Frequentes

P: Como faço para escolher entre transições CSS e @keyframes CSS? R: Use transições CSS para transições simples (opacidade/transformação). Use @keyframes ou GSAP para animações complexas (em várias etapas, baseadas em física). O Vue Transitions oferece suporte a ambas.

P: O TransitionGroup exige o seletor :key? R: Sim. <TransitionGroup> Os elementos filhos devem ser identificados de forma exclusiva usando :key; caso contrário, a animação não será acionada.

P: Como faço para implementar uma animação de “transição de página”? R: Coloque-a entre <router-view v-slot="{ Component }"> + <Transition>. Sempre que a rota mudar, o componente será atualizado, acionando uma transição.

P: Qual é a finalidade de mode="out-in"? R: Ele garante que o componente que está saindo conclua sua animação antes que o componente que está entrando comece. Isso evita que os dois componentes sejam exibidos ao mesmo tempo (sobrepondo-se).

P: É possível usar hooks de JavaScript e classes CSS juntos? R: Sim. <Transition :css="false" @enter="onEnter"> Desative as classes CSS e use apenas hooks de JavaScript. Ou ative ambos (use classes CSS para estilização e hooks de JavaScript para callbacks).

P: O que posso fazer se as animações estiverem lentas? R: (1) Use transform e opacity (aceleradas por GPU); (2) Evite propriedades que acionem o layout (width, height, top); (3) Reduza o número de elementos que estão sendo animados simultaneamente.

P: Como faço para usar o Animate.css com o Vue? R: Use enter-active-class="animate__animated animate__fadeIn" para mapear os nomes das classes do Animate.css para os hooks do Vue.


📖 Resumo


📝 Exercícios

  1. Questões básicas (Dificuldade: ⭐)

    Implemente um modal simples com efeito de fade-in/fade-out:

    • Clique no botão para abrir a janela modal
    • Fade in em 0,3 segundos
    • Clique para fechar (desaparecer gradualmente)
    • Fade-in e fade-out sincronizados da máscara de fundo
  2. Problemas avançados (Dificuldade: ⭐⭐)

    Implementar uma animação de lista com o TransitionGroup:

    • 5 tarefas a fazer
    • Entrada gradual do novo item (0,5 segundos)
    • Fazer os itens excluídos desaparecerem gradualmente (0,5 segundos + position: absolute)
    • Outros itens se movem suavemente durante a classificação (.list-move)
  3. Problema desafiador (Dificuldade: ⭐⭐⭐)

    Implementar um sistema completo de “animação de transição de página”:

    1. Animação de fade + deslizamento ao alternar entre rotas
    2. Três tipos de animações para adicionar, excluir e ordenar itens em uma lista
    3. A combinação “scale + fade” para janelas pop-up modais
    4. Animações complexas de linha do tempo com integração ao GSAP
    5. Teste comparativo de 5 bibliotecas de animação de terceiros
    6. Otimização de desempenho (aceleração por GPU + a ser alterado)
Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%