Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

Vue Transitions and Animations

The <Transition> Component

Vue's built-in <Transition> component applies enter/leave animations to a single element or component. It automatically adds CSS classes at the right moments, or you can use JavaScript hooks for full control.

ClassWhen applied
v-enter-fromStart state of enter — added before element is inserted
v-enter-activeActive state of enter — applied during entire enter phase
v-enter-toEnd state of enter — added after element is inserted
v-leave-fromStart state of leave
v-leave-activeActive state of leave
v-leave-toEnd state of leave
Transition, TransitionGroup, CSS Animations
<template>
  <div>
    <button @click="show = !show">Toggle</button>

    <!-- Basic fade transition -->
    <Transition name="fade">
      <p v-if="show">Hello, I fade in and out!</p>
    </Transition>

    <!-- Slide transition -->
    <Transition name="slide">
      <div v-if="show" class="panel">Sliding panel</div>
    </Transition>

    <!-- Mode: out-in (leave first, then enter) -->
    <Transition name="fade" mode="out-in">
      <component :is="currentView" :key="currentView" />
    </Transition>

    <!-- appear: animate on initial render -->
    <Transition name="fade" appear>
      <p>I animate when the page loads</p>
    </Transition>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const show = ref(true)
const currentView = ref('HomeView')
</script>

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

/* Slide transition */
.slide-enter-active {
  transition: all 0.3s ease-out;
}
.slide-leave-active {
  transition: all 0.3s ease-in;
}
.slide-enter-from {
  transform: translateX(-100%);
  opacity: 0;
}
.slide-leave-to {
  transform: translateX(100%);
  opacity: 0;
}

/* Scale + fade */
.scale-enter-active,
.scale-leave-active {
  transition: all 0.25s ease;
}
.scale-enter-from,
.scale-leave-to {
  transform: scale(0.9);
  opacity: 0;
}
</style>
<!-- TransitionGroup — animate lists -->
<template>
  <div>
    <input v-model="newItem" @keyup.enter="addItem" placeholder="Add item" />

    <TransitionGroup name="list" tag="ul">
      <li v-for="item in items" :key="item.id">
        {{ item.text }}
        <button @click="removeItem(item.id)">✕</button>
      </li>
    </TransitionGroup>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const newItem = ref('')
const items = ref([
  { id: 1, text: 'Learn Vue' },
  { id: 2, text: 'Build something' },
])

function addItem() {
  if (!newItem.value.trim()) return
  items.value.push({ id: Date.now(), text: newItem.value })
  newItem.value = ''
}

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

<style>
/* List item enter/leave */
.list-enter-active,
.list-leave-active {
  transition: all 0.4s ease;
}
.list-enter-from {
  opacity: 0;
  transform: translateX(-30px);
}
.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

/* Smooth repositioning of remaining items */
.list-move {
  transition: transform 0.4s ease;
}

/* Prevent layout shift during leave */
.list-leave-active {
  position: absolute;
}
</style>
<!-- JavaScript hooks — full control with GSAP or Web Animations API -->
<template>
  <Transition
    @before-enter="onBeforeEnter"
    @enter="onEnter"
    @after-enter="onAfterEnter"
    @enter-cancelled="onEnterCancelled"
    @before-leave="onBeforeLeave"
    @leave="onLeave"
    @after-leave="onAfterLeave"
    :css="false"
  >
    <div v-if="show" class="box">Animated box</div>
  </Transition>
</template>

<script setup>
import { ref } from 'vue'

const show = ref(true)

// :css="false" — disable CSS transitions, use JS only

function onBeforeEnter(el) {
  el.style.opacity = '0'
  el.style.transform = 'scale(0.8)'
}

function onEnter(el, done) {
  // Use Web Animations API
  el.animate([
    { opacity: 0, transform: 'scale(0.8)' },
    { opacity: 1, transform: 'scale(1)' }
  ], {
    duration: 400,
    easing: 'ease-out'
  }).onfinish = done  // call done() when animation completes
}

function onLeave(el, done) {
  el.animate([
    { opacity: 1, transform: 'scale(1)' },
    { opacity: 0, transform: 'scale(0.8)' }
  ], {
    duration: 300,
    easing: 'ease-in'
  }).onfinish = done
}

function onAfterEnter(el) { console.log('Enter complete') }
function onAfterLeave(el) { console.log('Leave complete') }
function onBeforeLeave(el) { /* ... */ }
function onEnterCancelled(el) { /* ... */ }
</script>

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.