Vue3中使用transition-group实现点击切换元素带显隐动画
问题根因
你的代码有3个核心错误导致动画不生效:
- 过渡标签绑定位置错误:当前
<transition-group>包裹的是点击选项列表,这部分内容在点击时不会新增/删除,永远不会触发进入/离开动画;真正需要做新旧内容切换的element显示区域,完全没有被过渡标签包裹。 - 过渡CSS逻辑错误:给
.list-leave-active设置display: none会让元素直接瞬间隐藏,CSS过渡不支持display属性的动画计算,元素会直接跳过1s的过渡时长直接消失。同时你只写了进入初始状态,缺少进入结束、离开状态的对应类定义,动画链路不完整。 - 缺少动画触发必要的key属性:动态切换的内容如果不绑定唯一key,Vue会默认复用DOM节点,不会触发节点的进入/离开生命周期,自然不会执行动画。
修复步骤
1. 调整模板结构
把不需要动画的选项列表移出过渡标签,给需要做切换动画的内容区域单独添加普通<transition>标签(单节点切换不需要用transition-group),同时给动态内容绑定唯一key触发节点更新:
<div id="app"> <!-- 选项列表无动画,直接渲染 --> <div style="cursor:pointer" v-for="(item,key,i) in array" :key="i" class="list-item" > <div @click="select(key)">{{key}}</div> </div> <!-- 动画区域单独包裹,绑定key --> <transition name="fade"> <div :key="element" class="content-item"> {{element}} </div> </transition> </div>
原有脚本的
select赋值逻辑不需要修改,仅需删除未使用的HelloWorld组件注册即可,不影响动画执行。
2. 修正过渡样式
删除原来错误的display: none设置,补全过渡类名,给离开阶段的元素设置绝对定位避免占位,实现新旧元素同步动画效果:
/* 统一设置进入、离开的过渡时长和缓动效果 */ .fade-enter-active, .fade-leave-active { transition: all 1s ease; } /* 进入初始状态、离开结束状态:透明+向上偏移 */ .fade-enter-from, .fade-leave-to { opacity: 0; transform: translateY(-12px); } /* 离开阶段元素绝对定位,不占文档流位置,让新元素可以同步入场 */ .fade-leave-active { position: absolute; } /* 给动画父容器加相对定位,避免离开元素定位偏移 */ #app { position: relative; }
补充说明
- 不要给过渡标签加
mode="out-in"或者mode="in-out"属性,这两个属性会强制让进入、离开动画排队执行,加了就没法实现新旧元素同步动画的效果。 - 如果需要做列表的增删动画,再使用
transition-group,且必须给每个循环项绑定业务唯一的key,不要用数组索引当key,否则会出现动画错乱。
内容的提问来源于stack exchange,提问作者mobiw
相关产品推荐
相关产品推荐

