Vue Animations with v-for

Welcome to The Coding College! When working with dynamic lists in Vue, v-for is the go-to directive for rendering multiple elements. Adding animations to these lists can improve user experience, especially when items are added, removed, or reordered. Vue makes this simple with the transition-group component, designed to animate changes in a list.

This guide explores how to create stunning animations with v-for and transition-group.

Why Animate Lists?

Animating lists enhances usability by:

  • Providing visual feedback for user actions.
  • Making the UI feel more dynamic and engaging.
  • Clarifying changes, such as additions, removals, or reorderings.

Basics: Using transition-group with v-for

The transition-group component is used to animate multiple elements rendered using v-for. It works similarly to the transition component but is specifically designed for lists.

Example: Animated List with v-for

<template>
  <div>
    <button @click="addItem">Add Item</button>
    <button @click="removeItem">Remove Item</button>
    <transition-group name="list" tag="ul">
      <li v-for="(item, index) in items" :key="item" class="list-item">
        {{ item }}
      </li>
    </transition-group>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [1, 2, 3, 4]
    };
  },
  methods: {
    addItem() {
      this.items.push(this.items.length + 1);
    },
    removeItem() {
      this.items.pop();
    }
  }
};
</script>

<style>
.list-item {
  list-style: none;
  margin: 5px 0;
  padding: 10px;
  background: #f0f0f0;
  border-radius: 4px;
}

.list-enter-active, .list-leave-active {
  transition: all 0.5s;
}
.list-enter, .list-leave-to {
  opacity: 0;
  transform: translateY(20px);
}
</style>

Key Features of transition-group

  • tag: Specifies the wrapper element (e.g., ul, div).
  • name: Sets the base name for CSS transition classes (e.g., list-enter-active).
  • key: Ensures Vue can track and animate individual list items.

Animating Reordering of Items

When items are reordered, Vue can animate their movement.

Example: Drag-and-Drop Reordering

<template>
  <div>
    <button @click="shuffle">Shuffle Items</button>
    <transition-group name="shuffle" tag="ul">
      <li v-for="item in items" :key="item" class="shuffle-item">
        {{ item }}
      </li>
    </transition-group>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [1, 2, 3, 4, 5]
    };
  },
  methods: {
    shuffle() {
      this.items = this.items.sort(() => Math.random() - 0.5);
    }
  }
};
</script>

<style>
.shuffle-item {
  list-style: none;
  margin: 5px 0;
  padding: 10px;
  background: #d4e6f1;
  border-radius: 4px;
  display: inline-block;
  width: 100px;
  text-align: center;
}

.shuffle-move {
  transition: transform 0.5s;
}
</style>

Adding the move Class

Vue automatically applies the *-move class to handle the transitions of reordered items (e.g., shuffle-move).

JavaScript Hook Animations with v-for

For more complex animations, you can use JavaScript hooks with transition-group.

Example: Custom JavaScript Animations

<template>
  <div>
    <button @click="addItem">Add Item</button>
    <transition-group
      tag="div"
      name="custom"
      @before-enter="beforeEnter"
      @enter="enter"
      @leave="leave"
    >
      <div v-for="(item, index) in items" :key="item" class="box">
        {{ item }}
      </div>
    </transition-group>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [1, 2, 3]
    };
  },
  methods: {
    addItem() {
      this.items.push(this.items.length + 1);
    },
    beforeEnter(el) {
      el.style.opacity = 0;
      el.style.transform = "scale(0)";
    },
    enter(el, done) {
      setTimeout(() => {
        el.style.transition = "all 0.5s";
        el.style.opacity = 1;
        el.style.transform = "scale(1)";
        done();
      }, 100);
    },
    leave(el, done) {
      el.style.transition = "all 0.5s";
      el.style.opacity = 0;
      el.style.transform = "scale(0)";
      setTimeout(() => done(), 500);
    }
  }
};
</script>

<style>
.box {
  width: 100px;
  height: 100px;
  margin: 10px;
  background: #82e0aa;
  display: inline-block;
  text-align: center;
  line-height: 100px;
  border-radius: 4px;
}
</style>

Best Practices for Animating with v-for

  1. Use Unique Keys: Ensure that :key is unique for each item to prevent issues with tracking and animations.
  2. Keep Transitions Smooth: Avoid animations that are too fast or slow; 0.3–0.5 seconds is usually optimal.
  3. Optimize Performance: Test animations for performance, especially with large datasets.
  4. Fallback for Older Browsers: Provide graceful degradation for browsers that don’t support animations.
  5. Be Accessible: Respect user preferences for reduced motion when adding animations.

Conclusion

Animating lists in Vue with v-for and transition-group is a straightforward way to enhance your application’s interactivity and aesthetics. Whether you’re adding, removing, or reordering items, Vue’s animation tools make it easy to implement visually appealing transitions.

For more tutorials and tips on Vue and web development, visit The Coding College.

Leave a Comment