Vue.js列表项移除动画异常:非末尾项动画失效问题
解决Vue列表项移除动画仅末尾项生效的问题
你遇到的这个问题其实是Vue列表渲染中很常见的坑——没有给v-for绑定唯一的key值,再加上用单个transition处理列表项过渡的方式不对,导致移除非末尾项时动画无法触发。
问题根源
Vue在更新用v-for渲染的列表时,如果没有指定唯一的key,会采用「就地复用」的策略:当你删除中间项时,后面的组件会被重新赋值(比如原来的第3项会变成第2项的内容),而不是被真正移除,所以transition的离开动画根本不会触发,看起来元素就直接消失了;只有最后一项被真正从DOM中移除时,动画才会正常显示。
解决方案
我们需要用Vue专门为列表过渡设计的<transition-group>组件,同时给v-for绑定唯一的key,这样就能保证每个列表项的过渡状态都能被正确管理。
下面是修改后的完整代码:
HTML 代码
<div id="vue-instance"> <ul> <transition-group name="bounce"> <hello v-for="(item, index) in list" :key="item" :ind="item" @removeit="removeit('extra', index)" ></hello> </transition-group> </ul> </div>
JS 代码
Vue.component('hello', { template: '<li>{{ind}} <a @click="removeit(ind)">remove</a></li>', props: ['ind'], methods: { removeit(ind) { this.$emit('removeit') } } }) var vm = new Vue({ el: '#vue-instance', data: { list: [1,2,3,4,5,6,7,8,9,10] }, methods: { removeit (extra, index) { this.list.splice(index, 1) } } });
CSS 代码
.bounce-enter-active { animation: bounce-in .7s; } .bounce-leave-active { animation: bounce-in .7s reverse; } @keyframes bounce-in { 0% { transform: scale(0); } 50% { transform: scale(1.20); } 100% { transform: scale(1); } }
关键修改说明
- 替换单个
transition为transition-group:这个组件专门用于列表元素的过渡,能自动为每个列表项处理进入、离开甚至排序的动画状态,比给每个子组件单独加transition更可靠。 - 添加
:key="item":这里用列表项的item值作为唯一key(因为你的列表项都是唯一数字),确保Vue能精准识别每个元素的身份,不会在列表更新时错误地复用组件。 - 移除子组件内的
transition:因为transition-group已经接管了整个列表的过渡管理,子组件不需要再单独包裹transition标签了。
现在你再测试一下,不管移除哪个位置的列表项,都会触发你设置的bounce离开动画,问题就解决啦~
内容的提问来源于stack exchange,提问作者coure2011
相关产品推荐
相关产品推荐

