Vue滑块组件使用Transition时行为异常求助
Vue滑动切换组件:解决动画失效与布局错乱问题
问题根源
- 右侧元素滑入无动画:
v-show切换时,绝对定位元素的初始状态没触发enter-from样式,直接显示出来了。 - 过渡时父元素被撑开:第一个元素没脱离正常流,离开动画期间还占着布局空间,和绝对定位的第二个元素同时显示,导致布局乱了。
- 绝对定位丢父元素高度:单个绝对定位元素撑不起父容器高度,得有个占位元素维持高度。
解决办法
- 统一元素定位:把两个内容元素都设为绝对定位,让它们在同一层重叠,避免布局被撑开。
- 自动适配高度:加个占位元素,用
visibility: hidden隐藏但保留高度,父元素会自动匹配内容的高度,不用硬写数值。 - 修复动画触发:调整
Transition的使用方式,确保元素显示/隐藏时能触发完整的进入/离开动画,同时修正CSS中无效的opacity值。
修改后的完整代码
<script setup> import { ref } from 'vue'; const isActivated = ref(false) </script> <template> <div class="p-2 relative overflow-hidden"> <!-- 高度占位:同时包含两个slot,确保父容器适配最大内容高度 --> <div class="visibility-hidden"> <slot name="first-content" /> <slot name="second-content" /> </div> <!-- 第一个内容:向左滑出/滑入 --> <Transition name="slide-left"> <div v-show="!isActivated" class="w-full absolute top-0 left-0"> <slot name="first-content" /> </div> </Transition> <!-- 第二个内容:向右滑入/滑出 --> <Transition name="slide-right"> <div v-show="isActivated" class="w-full absolute top-0 left-0"> <slot name="second-content" /> </div> </Transition> <div @click.prevent.stop="isActivated = !isActivated" class="px-2 absolute top-0 right-2"> <slot name="trigger" /> </div> </div> </template> <style> .visibility-hidden { visibility: hidden; } .slide-left-enter-active, .slide-left-leave-active, .slide-right-enter-active, .slide-right-leave-active { transition: all 0.8s ease; } .slide-left-enter-from, .slide-left-leave-to { transform: translateX(-100%); opacity: 0; } .slide-left-enter-to, .slide-left-leave-from { transform: translateX(0); opacity: 1; } .slide-right-enter-from, .slide-right-leave-to { transform: translateX(100%); opacity: 0; } .slide-right-enter-to, .slide-right-leave-from { transform: translateX(0); opacity: 1; } </style>
关键说明
- 高度占位逻辑:占位元素同时渲染两个slot的内容,用
visibility: hidden隐藏后,父容器会自动取两个内容中最高的高度,完美适配任意内容高度。 - 重叠布局:两个内容元素都用
absolute top-0 left-0,完全重叠在父容器内,过渡期间不会互相影响布局。 - 动画修正:把原代码中
opacity:100改成opacity:1(CSS中opacity取值范围是0到1,100是无效值),确保透明度动画正常工作;同时给过渡加了ease曲线,动画更自然。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

