Bootstrap

Vue 3 TransitionGroup 深入解析:动画原理 + 代码示例

前言

从实战中学习

在这里插入图片描述

TransitionGroup 动画总结

场景适用关键点
列表新增/删除需要 key 唯一
元素重新排序使用 move-class
首次渲染动画添加 appear
单个元素切换使用 Transition 代替

1. 基本知识

TransitionGroup 是 Vue 提供的一个特殊的过渡组件,允许对多个元素的进入、离开和移动进行动画处理,与 Transition 类似,但主要用于列表或动态元素组的动画过渡

TransitionGroup 主要用于对一组元素进行添加、移除和位置变换时的动画处理,常用于列表项的增删和重新排序

特性说明备注
appear组件初次渲染时执行进入动画仅影响初次加载
tag指定渲染的 HTML 标签默认为 span
move-class元素位置发生变化时的动画类适用于排序
enter-active-class进入时的动画类用于控制进入动画
leave-active-class离开时的动画类用于控制消失动画
key必须为每个子元素提供唯一 keyVue 依赖 key 进行 DOM diff
@before-enter进入动画前的钩子-
@enter进入动画时的钩子-
@after-enter进入动画完成后的钩子-
@before-leave离开动画前的钩子-
@leave离开动画时的钩子-
@after-leave离开动画完成后的钩子-

TransitionGroup 与 Transition 的区别

对比项TransitionTransitionGroup
作用处理单个元素的进入/离开动画处理多个元素的进入/离开/移动动画
是否需要 key不需要必须
适用场景单个元素的显示/隐藏列表或动态元素的动画处理
是否支持 move❌ 不支持✅ 支持
是否保留 tag会被替换掉不会替换掉

2. Demo

🌟 示例 1:列表元素的进入、离开、移动

  • tag="ul" 让 TransitionGroup 渲染为 ul
  • name="list" 让 Vue 自动应用 list- 前缀的过渡类
  • enter-active-class="animate__animated animate__fadeIn" 让新项渐入
  • leave-active-class="animate__animated animate__fadeOut" 让移除项渐出
  • move-class="animate__animated animate__fadeInUp" 让列表项重新排序时有动画
<template>
  <div>
    <button @click="addItem">添加项</button>
    <button @click="removeItem">删除项</button>
    <transition-group
      tag="ul"
      name="list"
      appear
      enter-active-class="animate__animated animate__fadeIn"
      leave-active-class="animate__animated animate__fadeOut"
      move-class="animate__animated animate__fadeInUp"
    >
      <li v-for="item in items" :key="item" class="list-item">
        {{ item }}
      </li>
    </transition-group>
  </div>
</template>

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

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

const addItem = () => {
  items.value.push(items.value.length + 1)
}

const removeItem = () => {
  items.value.pop()
}
</script>

<style scoped>
.list-item {
  list-style: none;
  padding: 10px;
  margin: 5px;
  background: lightblue;
  border-radius: 5px;
  text-align: center;
}
</style>

🌟 示例 2:move-class 处理元素排序动画

  • move-class="move" 让 Vue 监听元素的位置变化
  • transition: transform 0.5s; 让 li 在位置变化时平滑移动
  • shuffleItems 方法打乱数组,实现随机排序动画
<template>
  <div>
    <button @click="shuffleItems">随机排序</button>
    <transition-group tag="ul" class="list" move-class="move">
      <li v-for="item in items" :key="item" class="list-item">
        {{ item }}
      </li>
    </transition-group>
  </div>
</template>

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

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

const shuffleItems = () => {
  items.value = items.value.sort(() => Math.random() - 0.5)
}
</script>

<style scoped>
.list {
  padding: 0;
}

.list-item {
  list-style: none;
  padding: 10px;
  margin: 5px;
  background: lightblue;
  border-radius: 5px;
  text-align: center;
}

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