Vue 动画完全指南(二):<TransitionGroup> 列表动画与进阶用法

📅 2026/7/13 8:47:21
Vue 动画完全指南(二):<TransitionGroup> 列表动画与进阶用法
前言在上一篇中我们掌握了Transition组件的核心用法实现了单个元素的进入/离开动画。但实际开发中我们更多需要处理的是列表——增删改、排序、筛选……这些场景下单个元素的过渡组件就不够用了。本篇将带你掌握TransitionGroup组件搞定列表场景的流畅过渡动画让列表的每一个变化都流畅自然。核心一TransitionvsTransitionGroup对比维度TransitionTransitionGroup适用场景单个元素/组件v-for 渲染的列表多元素动画内部根元素只能有1个可以有多个是否必须绑定 key否有多个元素时才需要是每个子元素必须绑定唯一 key额外能力无支持 move 类元素移动动画渲染方式不额外渲染容器默认渲染为 可用 tag 属性修改核心二:TransitionGroup的 4 个核心点①tag 属性控制渲染的 HTML 标签可设置 ul、div、ol 等替代默认的 span适配列表语义化场景②move动画类专属核心能力监听列表元素位置变化实现平滑位移过渡解决删除、排序时的页面跳动问题防止删除时跳动③唯一 keyVue 依靠 key 精准追踪每一个列表 DOM 元素是列表动画生效的前提④name 属性同 控制类名前缀用于自定义动画类名前缀统一管理过渡样式核心三基础示例——待办列表的增删动画模仿第一篇的淡入淡出示例给一个最基础的列表增删template div div styledisplay: flex; gap: 10px; margin-bottom: 16px; input v-modelnewItem keyup.enteraddItem placeholder输入任务... / button clickaddItem添加/button /div TransitionGroup tagul namelist classtodo-list li v-foritem in list :keyitem.id classtodo-item span{{ item.text }}/span button clickremoveItem(item.id)删除/button /li /TransitionGroup /div /template script setup import { ref } from vue let id 0 const list ref([{ id: id, text: 学习 TransitionGroup }]) const newItem ref() const addItem () { if (!newItem.value.trim()) return list.value.push({ id: id, text: newItem.value }) newItem.value } const removeItem (id) { list.value list.value.filter(item item.id ! id) } /script style scoped /* 关键列表动画类名 */ .list-enter-from, .list-leave-to { opacity: 0; transform: translateY(-20px); } .list-enter-active, .list-leave-active { transition: all 0.3s ease; } /* 删除时绝对定位防止其他元素跳动 */ .list-leave-active { position: absolute; width: 100%; } /* 元素移动时的平滑过渡 */ .list-move { transition: transform 0.3s ease; } /style代码解读①TransitionGroup tagul渲染为 ul 标签替代默认的 span适配列表语义化结构② v-for 绑定 item.id 唯一 keyv-for“item in list” :key“item.id”保证 Vue 能精准识别每一个列表元素是动画生效的基础③.list-move处理元素位置变化让排序和删除时其他元素平滑移动避免生硬瞬移④ 删除动画添加position: absolute删除时把元素移出文档流防止其他元素瞬间占位、页面跳动核心四move 类的原理当列表中的元素位置发生变化比如删除一个元素排序、筛选等Vue 会计算每个元素新位置和旧位置的偏移量同时Vue 会自动为发生位移的元素添加 xxx-move 类只要该类设置了 transition 过渡属性就能实现平滑的位置移动动画。关键代码就是.list-move { transition: transform 0.3s; }核心五实战——带筛选和排序的列表动画增加一点复杂度让文章更有价值添加全部/未完成/已完成筛选添加按时间/按名称排序筛选和排序时列表元素会重新排列move 类会自动生效所有元素位置变动都会自带丝滑过渡效果无需额外写复杂动画逻辑。核心六路由页面切换搭配 router-view除了列表动画Transition 组件还常用于页面路由切换搭配modeout-in解决新旧页面重叠问题是项目必备进阶用法。router-view v-slot{ Component } Transition namepage modeout-in component :isComponent :key$route.path / /Transition /router-view/* 页面进入初始状态 */.page-enter-from{opacity:0;transform:translateX(20px);}/* 进入过渡动画 */.page-enter-active{transition:all 0.3s ease;}/* 页面离开最终状态 */.page-leave-to{opacity:0;transform:translateX(-20px);}/* 离开过渡动画 */.page-leave-active{transition:all 0.3s ease;}关键点mode“out-in” 先执行离开动画再执行进入动画防止新旧页面重叠。避坑指南⭐⭐⭐ 问题原因解决方案列表删除时其他元素跳上去没有给删除的元素设置绝对定位.list-leave-active { position: absolute; }列表动画不生效忘记绑定 key 或绑了 index绑定唯一、稳定、不随排序变化的 key如 item.id使用 v-show 没有离开动画v-show 不会销毁元素改用 v-if动画类名在 scoped 中不生效scoped 限制样式作用域使用 :deep() 穿透或去掉 scoped筛选排序时动画没有触发Vue 复用了 DOM 元素确保 :key 是唯一的且能反映元素身份总结核心概念一句话总结TransitionvsTransitionGroup单元素用前者多元素列表用后者tag 属性控制TransitionGroup渲染成什么标签move 类元素位置变化时的过渡动画关键代码 transition: transform 0.3s列表 key 规则必须绑定唯一且稳定的 key不能用 indexmode“out-in”页面切换时先离开再进入防止重叠下一篇预告路由切换与页面转场动画进阶以及如何结合 animate.css 做出更丰富的页面过渡效果。