Vue中移除列表项时如何实现下方元素平滑上移动画?
解决Vue Transition-Group删除元素时下方元素平滑上滑的问题
这个问题很常见,核心原因是你原来的离开动画只处理了元素的透明度和位移,但被删除的元素在动画过程中仍然占据着原来的空间,直到动画结束才会被DOM移除,所以下方元素会瞬间跳跃到新位置。我们可以通过调整CSS过渡,让被删除元素在淡出的同时逐渐收缩占位空间,配合Vue的player-move类实现下方元素的平滑上滑,完全不需要额外JS。
修改方案
只需要调整你的CSS样式,同时补全脚本里的方法(方便测试):
1. 完整脚本代码
new Vue({ el: "#app", data() { return { name: "", players: [ {id: 1, name: 'Player1'}, {id: 2, name: 'Player2'}, {id: 3, name: 'Player3'}, ], nextId: 4 } }, methods: { addPlayer: function () { if (this.name.trim()) { this.players.push({id: this.nextId++, name: this.name.trim()}); this.name = ''; } }, removePlayer: function (playerId) { this.players = this.players.filter(player => player.id !== playerId); } } });
2. 调整后的CSS代码
.form { margin:0 auto; width:400px; } .panel { width: 400px; margin: 10px auto; overflow: hidden; border: 1px solid; text-align: center; } .remove { float: right; cursor: pointer; text-decoration: underline; font-size: 12px; vertical-align: bottom } .player-enter, .player-leave-to { opacity: 0; } .player-enter { transform: translateY(30%); } /* 关键修改:让被删除元素在离开时收缩占位 */ .player-leave-to { transform: translateX(30%); height: 0; margin-top: 0; margin-bottom: 0; border-width: 0; /* 可选,让边框也平滑消失 */ } .player-enter-active, .player-leave-active { transition: all 1.5s; } /* 确保下方移动的元素有过渡效果 */ .player-move { transition: all 1.5s; }
为什么这样有效?
- 当元素被标记为删除时,
player-leave-to的样式会让它的高度、margin、边框逐渐变为0,同时保持透明度和位移的过渡——这样元素的占位空间会逐渐缩小,而不是瞬间消失。 - 下方的元素会因为上方元素的占位变化自然向上移动,Vue的
transition-group会自动给这些移动的元素添加player-move类,这个类的过渡效果会让移动过程变得平滑。 - 整个过程完全基于CSS过渡和Vue内置的动画钩子,不需要额外的JavaScript操作,完美符合你的需求。
避坑提示
你之前尝试的position:absolute之所以失效,是因为绝对定位会让元素瞬间脱离文档流,失去占位空间,导致下方元素立刻跳跃。而我们的方法是让元素在文档流中逐渐收缩,保留了布局的连续性,所以能实现平滑过渡。
内容的提问来源于stack exchange,提问作者arusev
相关产品推荐
相关产品推荐

