TailwindCSS动画结合v-for时失效问题求助
问题:多弹窗时过渡动画失效
我在屏幕右上角实现了一组可点击关闭的弹窗消息,每个弹窗都配置了slide-fade过渡效果。单个弹窗时动画正常工作,但多个弹窗并存时,过渡效果就失效了,求解决办法。
相关代码
popup.vue
<template> <Transition name="slide-fade" @click="close"> <div class="bg-green-100 opacity-95 rounded-lg py-5 px-6 mb-3 text-green-700 inline-flex items-center text-sm" role="alert"> <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="w-8 h-8 mr-2 fill-current" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path> </svg> {{ placeholder }} </div> </Transition> </template> <script> export default { name: 'popupComponent', methods: { close () { this.$emit('close', this.arrIndex) } }, props: { placeholder: String, arrIndex: Number } } </script> <style scoped> .slide-fade-enter-active { transition: all 0.3s ease-out; } .slide-fade-leave-active { transition: all 0.8s cubic-bezier(.25,.59,.63,.92); } .slide-fade-enter-from, .slide-fade-leave-to { transform: translateX(20px); opacity: 0; } </style>
App.vue
<template> <div class="absolute z-10 right-0 p-2 max-w-md"> <div class="flex flex-col gap-y-2 max-h-96 overflow-y-hidden"> <popup v-for="(content, index) in popup_content.slice().reverse()" :key="index" @close="closePopup" :arrIndex="(popup_status.length-1) - index" :placeholder="content"/> </div> </div> </template> <script> import popupComponent from './components/popup.vue' export default { data() { return { popup_content: ['Awesome!', 'Nice!'], } }, methods: { closePopup(index) { this.popup_content.splice(index, 1); } }, components: { 'popup': popupComponent }, name: 'App' } </script>
解决方案
1. 替换v-for的key值
当前用数组index作为key,当元素被删除时,后续元素的index会发生变化,Vue会复用现有组件而非重新渲染,导致过渡动画失效。需要改用每个弹窗的唯一标识作为key:
修改App.vue的data结构:
data() { return { popup_content: [ { id: 1, content: 'Awesome!' }, { id: 2, content: 'Nice!' } ], } }
更新v-for循环:
<popup v-for="(item, index) in popup_content.slice().reverse()" :key="item.id" @close="closePopup" :arrIndex="(popup_content.length-1) - index" :placeholder="item.content" />
2. 修正arrIndex的计算错误
原代码中误用了未定义的popup_status.length,应改为popup_content.length,否则会导致删除索引错误。
3. 给弹窗添加条件渲染控制
当前Transition组件没有绑定显示状态,关闭时组件直接被父组件删除,无法触发过渡动画。需要在popup.vue中添加v-if控制显示:
修改popup.vue的template:
<template> <Transition name="slide-fade"> <div v-if="visible" class="bg-green-100 opacity-95 rounded-lg py-5 px-6 mb-3 text-green-700 inline-flex items-center text-sm" role="alert" @click="close" > <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check-circle" class="w-8 h-8 mr-2 fill-current" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> <path fill="currentColor" d="M504 256c0 136.967-111.033 248-248 248S8 392.967 8 256 119.033 8 256 8s248 111.033 248 248zM227.314 387.314l184-184c6.248-6.248 6.248-16.379 0-22.627l-22.627-22.627c-6.248-6.249-16.379-6.249-22.628 0L216 308.118l-70.059-70.059c-6.248-6.248-16.379-6.248-22.628 0l-22.627 22.627c-6.248 6.248-6.248 16.379 0 22.627l104 104c6.249 6.249 16.379 6.249 22.628.001z"></path> </svg> {{ placeholder }} </div> </Transition> </template>
更新popup.vue的script,添加显示状态控制:
export default { name: 'popupComponent', data() { return { visible: true } }, methods: { close () { this.visible = false; // 等待过渡动画结束后通知父组件删除元素 setTimeout(() => { this.$emit('close', this.arrIndex) }, 800); // 对应leave-active的0.8s过渡时长 } }, props: { placeholder: String, arrIndex: Number } }
内容的提问来源于stack exchange,提问作者JoshJohnson
相关产品推荐
相关产品推荐

