Transition Image in vue 3

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.

5 min read

November 20th, 2024

Nick Mousavi

Introduction

As you know Vue has 2 built-in components (

and
TransitionGroup
) that help you to make transitions and animation based on state changes.

Most

, developers traditionally use
v-if
with the
Transition
component to create animated element appearances and disappearances.

While

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

inside a
Transition
wrapper.

When the

show
data property toggles, the element appears and disappears with a fade effect.

IfComponent.vue
<!-- 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

comes into play!

Better Approach: Using
v-show
with
appear

appear
prop helps us to apply transition on the initial render.

ShowComponent.vue
<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.

v-if
and
v-show
?

The key difference is how they handle element rendering:

  • v-if
    completely removes the element from the DOM when the condition is false
  • v-show
    simply toggles the CSS
    display
    property, keeping the element in the DOM
  • v-if
    has higher toggle costs but lower initial render costs
  • v-show
    has lower toggle costs but slightly higher initial render costs
v-if
over
v-show
?

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
    and
    unmounted
    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
v-if
and
v-show
at the same time ?

For complex scenarios, and performance optimization consider using the

v-if
and
v-show
combination.

complex.vue
<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.
Tags:Vue