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 (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.

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 v-show 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.

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

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

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
Nick Mousavi
A small step forward is still progress.

To get in touch with Nick Mousavi,
please enter your email address below.

© 2020-present Nick Mousavi. All Rights Reserved.

Privacy Policy