如何使用Vue.js Transition实现按钮与折叠面板的位置交换
用Vue.js Transition实现折叠面板头部的位置交换动画
核心思路
要实现位置交换的平滑过渡动画,Vue的<transition-group>是最优方案——它专门针对列表的排序、新增/删除场景提供动画支持。首先需要把固定的面板结构重构为动态数组渲染,通过修改数组元素的顺序触发动画,同时用Vue状态统一控制折叠展示,避免和Bootstrap原生逻辑冲突。
完整实现代码
<html> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"> </script> <div id="app"> <div id="t_accordion"> <div class="accordion" id="accordionExample"> <!-- Transition Group:包裹动态列表,指定渲染标签和动画名称 --> <transition-group tag="div" name="panel-swap" class="panel-list"> <!-- 动态渲染面板项,用唯一id作为key --> <div class="accordion-item" v-for="(panel, index) in panels" :key="panel.id"> <h2 class="accordion-header" :id="`heading${panel.id}`"> <button class="d-flex bg-white mx-auto w-100" @click="swapAndToggle(index)"> <span class="flex-grow-1 text-center">{{ panel.title }}</span> <button class="accordion-button" :class="{ collapsed: !panel.isActive }" type="button" @click.stop="panel.isActive = !panel.isActive"> </button> </button> </h2> <!-- 用Vue状态控制折叠显示 --> <div :id="`collapse${panel.id}`" class="accordion-collapse collapse" :class="{ show: panel.isActive }" :aria-labelledby="`heading${panel.id}`" data-bs-parent="#accordionExample"> <div class="accordion-body"> <strong>{{ panel.content }}</strong> </div> </div> </div> </transition-group> </div> </div> </div> <script src="https://unpkg.com/vue@2"></script> <script> new Vue({ el: '#app', data() { return { // 数组存储面板数据:唯一id、标题、内容、激活状态 panels: [ { id: 1, title: 'User', content: 'User Content', isActive: false }, { id: 2, title: 'View', content: 'View Content', isActive: true } ] } }, methods: { swapAndToggle(index) { // 交换两个面板的位置 this.panels.reverse(); // 同步切换激活状态(可根据需求调整逻辑) this.panels.forEach(panel => { panel.isActive = !panel.isActive; }); } } }); </script> <style> /* 定义排序动画样式 */ .panel-swap-move { transition: transform 0.5s ease; /* 启用硬件加速,提升动画流畅度 */ will-change: transform; } </style> </html>
关键部分说明
- 动态数组渲染:将固定的两个面板改为
v-for遍历数组,每个面板用唯一id作为key——这是Vue列表动画生效的必要条件,不能用索引作为key。 - Transition Group:
<transition-group>会自动监听数组变化,为排序的元素添加过渡类,name="panel-swap"对应CSS中的动画类前缀。 - 交换逻辑:
swapAndToggle方法通过reverse()快速交换数组元素顺序,Vue会自动触发位置过渡动画。 - 状态控制:用
panel.isActive控制折叠面板的show类,替代Bootstrap原生的data-bs-toggle,避免状态不一致。 - CSS动画:
.panel-swap-move定义了位置变化时的过渡效果,transform属性实现平滑位移,可根据需求调整动画时长和缓动函数。
扩展优化
- 如果需要更丰富的动画(如交换时的透明度、缩放变化),可以添加
panel-swap-enter-active、panel-swap-leave-active类定义进入/离开动画。 - 若要保留Bootstrap原生折叠逻辑,可手动调用
new bootstrap.Collapse()API更新状态,但建议用Vue状态统一控制更可靠。
内容的提问来源于stack exchange,提问作者16_018_RHR
相关产品推荐
相关产品推荐

