
How to use Vue Transition Component without v-if
In this article we want to explore how we can use vue transition component without using v-if by using v-show.
Introduction
As you know Vue has 2 built-in components (Transition
and TransitionGroup
) that help you to make transitions and animation based on state changes.
Most Vue.js
, developers traditionally use v-if
with the Transition
component to create animated element appearances and disappearances.
While
v-if
works well, it completely removes elements from the DOM, which can sometimes lead to unnecessary re-rendering and performance overhead and also SEO issues.
The Typical Way to use Transition Component
The typical pattern involves conditionally rendering an element using v-if
inside a Transition
wrapper.
When the show
data property toggles, the element appears and disappears with a fade effect.
<!-- Traditional Approach with v-if -->
<template>
<div>
<button @click="show = !show">Toggle Element</button>
<!-- we named the transition so instead of v-leave-to we refer to fade-leave-to -->
<Transition name="fade">
<div v-if="show">
<p>I'm here!</p>
</div>
</Transition>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const show = ref(false)
</script>
<style>
.fade-enter-active,
.fade-leave-active {
opacity: 1;
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0.01;
transition: opacity 0.5s ease;
}
</style>
Problem
But the problem is that show
is false and the <p>I'm here!</p>
will not appear in HTML❗
What we can do?
Short answer: set true
as default value of show
state.
What if we want to have default value of false
🤔?
That's when v-show
comes into play!
Better Approach: Using v-show
with appear
appear
prop helps us to apply transition on the initial render.
<template>
<div>
<button @click="show = !show">Toggle Element</button>
<transition name="fade" appear>
<div v-show="show">
<p>I'm here!</p>
</div>
</transition>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const show = ref(false)
</script>
<style>
.fade-appear-active,
.fade-enter-active,
.fade-leave-active {
opacity: 1;
transition: opacity 0.5s ease;
}
.fade-appear-from,
.fade-enter-from,
.fade-leave-to {
opacity: 0.01;
transition: opacity 0.5s ease;
}
</style>
Now we have <p>I'm here!</p>
element on the initial render of HTML.
The key difference is how they handle element rendering:
v-if
completely removes the element from the DOM when the condition is falsev-show
simply toggles the CSSdisplay
property, keeping the element in the DOMv-if
has higher toggle costs but lower initial render costsv-show
has lower toggle costs but slightly higher initial render costs
Choose v-if
when:
- The condition rarely changes
- You want to save resources by not rendering unnecessary elements
- The element won't be toggled frequently
- You're working with heavy components that shouldn't be kept in memory
Choose v-show
when:
- The element will be toggled frequently
- You want to maintain the element's state
- Performance of quick toggling is more important
- You need smoother animations
Yes, You can combine multiple CSS classes and properties:
<template>
<Transition
appear
appear-class="custom-appear"
appear-active-class="active-appear"
appear-to-class="to-appear">
<div v-show="isVisible">
Complex Transition Content
</div>
</Transition>
</template>
This allows granular control over initial render animations, letting you define specific classes for different stages of the appear transition.
v-if
triggers full component destruction and re-creation- Calls
beforeUnmount
andunmounted
hooks - Completely reinitializes the component on re-render
v-show
keeps the component instance alive- Only toggles visibility
- Maintains component state and avoids unnecessary re-initialization
- More efficient for frequently toggled elements
For complex scenarios, and performance optimization consider using the v-if
and v-show
combination.
<template>
<Transition name="fade">
<div v-if="shouldRender" v-show="isVisible">
Optimized Conditional Content
</div>
</Transition>
</template>
- Prevents initial rendering of unnecessary elements (
v-if
) - Provides smooth toggling (
v-show
) - Minimizes unnecessary DOM manipulations and re-creation.