You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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>

关键部分说明

  1. 动态数组渲染:将固定的两个面板改为v-for遍历数组,每个面板用唯一id作为key——这是Vue列表动画生效的必要条件,不能用索引作为key。
  2. Transition Group:<transition-group>会自动监听数组变化,为排序的元素添加过渡类,name="panel-swap"对应CSS中的动画类前缀。
  3. 交换逻辑:swapAndToggle方法通过reverse()快速交换数组元素顺序,Vue会自动触发位置过渡动画。
  4. 状态控制:用panel.isActive控制折叠面板的show类,替代Bootstrap原生的data-bs-toggle,避免状态不一致。
  5. CSS动画:.panel-swap-move定义了位置变化时的过渡效果,transform属性实现平滑位移,可根据需求调整动画时长和缓动函数。

扩展优化

  • 如果需要更丰富的动画(如交换时的透明度、缩放变化),可以添加panel-swap-enter-active、panel-swap-leave-active类定义进入/离开动画。
  • 若要保留Bootstrap原生折叠逻辑,可手动调用new bootstrap.Collapse()API更新状态,但建议用Vue状态统一控制更可靠。

内容的提问来源于stack exchange,提问作者16_018_RHR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 03:40:22