Skip to content

Vue Transitions and Animations

Vue provides two built-in components, <Transition> and <TransitionGroup>, that help us easily add transition and animation effects to elements that are entering, leaving, or changing in lists.

The <Transition> Component

<Transition> is a built-in component, which means it can be used in any component's template without registration. It can apply animations to the entering and leaving of an element or component.

It supports scenarios including:

  • Conditional rendering triggered by v-if or v-show.
  • Dynamic components switched by <component>.
  • Route transitions.

Usage

Simply wrap the elements that need transition effects with the <Transition> component.

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

const show = ref(true)
</script>

<template>
  <button @click="show = !show">Toggle</button>
  <Transition name="fade">
    <p v-if="show">hello</p>
  </Transition>
</template>

<style>
/*
  Both enter and leave animations can be used.
  `v-enter-from`, `v-enter-active`, `v-enter-to`
  `v-leave-from`, `v-leave-active`, `v-leave-to`
*/

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

When the <p> element is inserted or removed, Vue will automatically add or remove a series of CSS classes.

  1. Enter:
    • fade-enter-from: The starting state of the enter animation.
    • fade-enter-active: Applied during the entire enter animation period.
    • fade-enter-to: The ending state of the enter animation.
  2. Leave:
    • fade-leave-from: The starting state of the leave animation.
    • fade-leave-active: Applied during the entire leave animation period.
    • fade-leave-to: The ending state of the leave animation.

Here, fade is the name prop of the <Transition> component. If there's no name, the class prefix defaults to v.

The <TransitionGroup> Component

<TransitionGroup> is a component for adding transition effects to elements or components in a v-for list. It has several characteristics:

  • By default, it doesn't render a wrapper element. But you can specify an element to render via the tag prop.
  • Transition effects are applied to each internal element, not the container itself.
  • You must provide a unique key attribute for each element in the list.
  • It can handle not only the entering and leaving of elements but also the movement of elements, which is achieved through the v-move class.

Example: List Move Transition

vue
<script setup>
import { ref } from 'vue'
import { shuffle } from 'lodash-es' // A utility function for shuffling arrays

const items = ref([1, 2, 3, 4, 5])

function shuffleItems() {
  items.value = shuffle(items.value)
}
</script>

<template>
  <button @click="shuffleItems">Shuffle</button>
  <TransitionGroup name="list" tag="ul">
    <li v-for="item in items" :key="item">
      {{ item }}
    </li>
  </TransitionGroup>
</template>

<style>
.list-move,
.list-enter-active,
.list-leave-active {
  transition: all 0.5s ease;
}

.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

/* Ensure the leaving element is removed from the layout flow so that the move animation can be calculated correctly. */
.list-leave-active {
  position: absolute;
}
</style>

The v-move class is applied when an element changes position. It's typically used to specify a CSS transition, making the list reordering process smooth.

Content is for learning and research only.