🎭 Vue.js Transitions: Making Your App Dance!
Imagine you’re a magician. When you make a rabbit appear, you don’t just poof it into existence—you wave your wand, add some sparkle, and the rabbit gracefully slides out of the hat. That’s exactly what Vue transitions do for your app!
🎬 What Are Transitions?
Think of transitions like stage directions in a play. When an actor enters the stage, they don’t just teleport—they walk in smoothly. When they leave, they exit gracefully. Vue transitions tell your elements HOW to enter and leave the screen.
Without transitions: Element appears → BLINK → Gone With transitions: Element appears → smooth fade → Gracefully disappears
🎁 The Transition Component
The <Transition> component is your magic wrapper. Wrap any element with it, and Vue automatically adds special powers!
<Transition>
<p v-if="show">Hello!</p>
</Transition>
Think of it like this:
- You have a gift (your element)
- The
<Transition>is the gift wrap - The wrap makes the gift look special when you open or close it!
When Does It Work?
The transition activates when:
- ✅
v-ifchanges (show/hide) - ✅
v-showchanges (visible/hidden) - ✅ Dynamic components switch
- ✅ Element added/removed from DOM
🎨 Transition Classes: The Six Magic Stages
Vue automatically adds 6 special classes during a transition. Think of them as costume changes during a performance!
graph TD A["Element Entering"] --> B["v-enter-from"] B --> C["v-enter-active"] C --> D["v-enter-to"] E["Element Leaving"] --> F["v-leave-from"] F --> G["v-leave-active"] G --> H["v-leave-to"]
🚪 ENTER Classes (Coming In)
| Class | When Applied | What It Means |
|---|---|---|
v-enter-from |
Before element appears | “I’m invisible, getting ready” |
v-enter-active |
During entire animation | “I’m moving/changing now!” |
v-enter-to |
After element appears | “I’m fully visible now” |
🚶 LEAVE Classes (Going Out)
| Class | When Applied | What It Means |
|---|---|---|
v-leave-from |
Before leaving starts | “I’m still here, about to go” |
v-leave-active |
During entire animation | “I’m fading/moving away!” |
v-leave-to |
After leaving ends | “I’m gone now” |
Simple Fade Example
.v-enter-from,
.v-leave-to {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s;
}
Translation: Start invisible → Animate for 0.5 seconds → End visible (and reverse for leaving)
🎛️ Transition CSS Properties
These are the tools in your magic toolkit. You can control:
The Big Three Properties
.v-enter-active {
transition: all 0.3s ease;
}
- Property: What changes? (
opacity,transform,all) - Duration: How long? (
0.3s,500ms) - Timing: How smooth? (
ease,linear,ease-in-out)
Common Timing Functions
| Name | Feeling | Best For |
|---|---|---|
ease |
Smooth, natural | Most animations |
linear |
Robot-like, steady | Progress bars |
ease-in |
Slow start, fast end | Elements leaving |
ease-out |
Fast start, slow end | Elements entering |
ease-in-out |
Slow-fast-slow | Elegant movements |
Slide + Fade Combo
.v-enter-from {
opacity: 0;
transform: translateY(-20px);
}
.v-enter-active {
transition: all 0.4s ease-out;
}
.v-leave-to {
opacity: 0;
transform: translateY(20px);
}
🏷️ Named Transitions
What if you want DIFFERENT animations for DIFFERENT elements? Give your transitions names!
<Transition name="fade">
<p v-if="show">I fade!</p>
</Transition>
<Transition name="slide">
<p v-if="show">I slide!</p>
</Transition>
How Names Change Classes
When you add name="fade", the classes become:
fade-enter-from(instead ofv-enter-from)fade-enter-active(instead ofv-enter-active)fade-leave-to(instead ofv-leave-to)- …and so on!
/* Fade transition */
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.3s;
}
/* Slide transition */
.slide-enter-from {
transform: translateX(-100%);
}
.slide-leave-to {
transform: translateX(100%);
}
.slide-enter-active,
.slide-leave-active {
transition: transform 0.5s;
}
⚡ JavaScript Hooks Transitions
Sometimes CSS isn’t enough. You need JavaScript power! Vue gives you special “hooks” (like checkpoints) during the transition.
<Transition
@before-enter="onBeforeEnter"
@enter="onEnter"
@after-enter="onAfterEnter"
@before-leave="onBeforeLeave"
@leave="onLeave"
@after-leave="onAfterLeave"
>
<div v-if="show">Hello!</div>
</Transition>
The Hook Timeline
graph TD A["before-enter"] --> B["enter"] B --> C["after-enter"] D["before-leave"] --> E["leave"] E --> F["after-leave"]
Example: Animate with JavaScript
function onEnter(el, done) {
// el = the element
// done = call when finished
el.style.opacity = 0;
setTimeout(() => {
el.style.opacity = 1;
done(); // Tell Vue we're done!
}, 500);
}
When to Use JS Hooks?
- ✅ Complex animations (bouncing, physics)
- ✅ Using animation libraries (GSAP, Anime.js)
- ✅ Need precise control
- ✅ Animations based on data/calculations
🔄 Transition Modes
The Problem: When one element leaves and another enters at the SAME time, they overlap! It looks messy.
The Solution: Transition modes!
mode="out-in" (Most Common)
Old element leaves FIRST, then new element enters.
<Transition mode="out-in">
<component :is="currentView" />
</Transition>
graph LR A["Old leaves"] --> B["Gap"] --> C["New enters"]
mode="in-out" (Rare)
New element enters FIRST, then old element leaves.
<Transition mode="in-out">
<component :is="currentView" />
</Transition>
graph LR A["New enters"] --> B["Overlap"] --> C["Old leaves"]
Real Example
<Transition name="fade" mode="out-in">
<button v-if="isOn" key="on">ON</button>
<button v-else key="off">OFF</button>
</Transition>
Important: Use :key to help Vue know they’re different elements!
⏱️ Transition Duration
Vue usually figures out how long your animation takes. But sometimes you need to tell it explicitly!
Using the Duration Prop
<!-- Same duration for enter and leave -->
<Transition :duration="500">
<div v-if="show">Hello</div>
</Transition>
<!-- Different durations -->
<Transition :duration="{ enter: 300, leave: 800 }">
<div v-if="show">Hello</div>
</Transition>
Why Specify Duration?
- Nested animations - Inner elements have their own timings
- JS animations - Vue can’t detect these automatically
- Precision - You want exact control
Duration Values
500= 500 milliseconds{ enter: 300, leave: 800 }= different times for each
🎬 Transition Appear
By default, transitions only work AFTER the page loads. What if you want the FIRST appearance to also animate?
The appear Prop
<Transition appear>
<div>I animate on first load!</div>
</Transition>
That’s it! Just add appear and your element animates when the page first loads.
Custom Appear Classes
Want different animation for initial appearance?
<Transition
appear
appear-from-class="initial-enter-from"
appear-active-class="initial-enter-active"
appear-to-class="initial-enter-to"
>
<div>Custom initial animation!</div>
</Transition>
Appear with JS Hooks
<Transition
appear
@appear="onAppear"
@after-appear="onAfterAppear"
>
<div>Hello World!</div>
</Transition>
function onAppear(el, done) {
// Animate the first appearance
el.style.transform = 'scale(0)';
setTimeout(() => {
el.style.transform = 'scale(1)';
done();
}, 500);
}
🎯 Quick Summary
| Feature | What It Does | Example |
|---|---|---|
<Transition> |
Wraps element for animation | <Transition><div v-if="show"> |
| Classes | 6 stages of animation | v-enter-from, v-leave-to |
| CSS Properties | Control animation style | transition: all 0.3s ease |
| Named | Different animations | name="fade" → fade-enter-from |
| JS Hooks | JavaScript control | @enter="onEnter" |
| Modes | Order of enter/leave | mode="out-in" |
| Duration | Explicit timing | :duration="500" |
| Appear | Animate first load | appear |
🚀 You’re Ready!
You now have all the tools to make your Vue app dance, fade, slide, and sparkle! Remember:
- Start simple - Just add
<Transition>and basic CSS - Name it - When you need multiple animation styles
- Use modes - When switching between elements
- Add appear - For that polished first impression
- Go JavaScript - When CSS isn’t powerful enough
Your elements are no longer just appearing and disappearing—they’re performing! 🎭
