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

使用Vue Transitions实现侧边栏隐藏时中间div同步展开动画

问题根源
  • 侧边栏动画使用transform: translate()实现,该属性仅改变元素的视觉渲染位置,不会修改元素在flex布局中占据的实际空间。侧边栏视觉上滑出的过程中,始终占用原有宽度,中间区域无法获得可用空间完成展开。
  • 侧边栏离开动画时长设置为0.5s,与进入动画、中间区域的0.3s过渡时长不统一,即使宽度联动生效也会出现动画节奏错位。
  • 中间区域不存在挂载/卸载的进入/离开逻辑,不需要套Vue的<transition>组件,套入后也不会触发对应的enter/leave状态;同时未绑定随侧边栏状态变化的可过渡属性,CSS transition无法自动触发过渡效果。
修复方案

不需要额外写watcher监听状态,利用CSS过渡配合flex布局的自动空间计算即可实现完全同步的动画效果,核心调整点:

  1. 侧边栏动画改为宽度从固定值线性收缩到0,让其在动画过程中实际占用的布局空间同步变化,flex会自动将腾出的空间分配给中间区域
  2. 侧边栏内容位移逻辑放到内层容器实现,避免外层宽度收缩时内容被挤压变形
  3. 所有动画时长统一为0.3s,保证节奏完全同步
  4. 容器添加overflow: hidden,避免动画过程中内容溢出

完整修正代码

JS 部分(原有逻辑无需修改)

var app = new Vue({
  el: '#app',
  data: {
    showSidebars: true,
  },
  methods: {
    animate() {
      this.showSidebars = !this.showSidebars;
    }
  }
});

CSS 部分

.container {
  display: flex;
  width: 600px;
  height: 200px;
  margin-bottom: 1em;
  overflow: hidden;
}

.sidebar {
  flex: 0 0 120px;
  background-color: #564D95;
}

.center {
  flex-grow: 1;
  background-color: #242C44;
  transition: all 0.3s linear;
}

.center:hover {
  flex-grow: 5;
}

/* Vue 过渡 统一动画时长 */
.expand-left-enter-active,
.expand-left-leave-active,
.expand-right-enter-active,
.expand-right-leave-active {
  transition: all 0.3s ease;
  overflow: hidden;
}

/* 进入初始态、离开结束态:宽度归0、透明 */
.expand-left-enter,
.expand-left-leave-to,
.expand-right-enter,
.expand-right-leave-to {
  flex: 0 0 0;
  opacity: 0;
}

/* 侧边栏内层内容做位移,避免外层宽度收缩挤压内容 */
.sidebar-inner {
  width: 120px;
  height: 100%;
  transition: transform 0.3s ease;
}
.expand-left-leave-to .sidebar-inner,
.expand-left-enter .sidebar-inner {
  transform: translateX(-100%);
}
.expand-right-leave-to .sidebar-inner,
.expand-right-enter .sidebar-inner {
  transform: translateX(100%);
}

HTML 部分

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div class="container">
    <!-- 左侧边栏 -->
    <transition name="expand-left">
      <div v-show="showSidebars" class="sidebar">
        <div class="sidebar-inner"></div>
      </div>
    </transition>

    <!-- 中间区域 -->
    <div class="center"></div>

    <!-- 右侧边栏 -->
    <transition name="expand-right">
      <div v-show="showSidebars" class="sidebar">
        <div class="sidebar-inner"></div>
      </div>
    </transition>
  </div>

  <button @click="animate">Animate</button>
</div>
实现说明
  • 动画过程中侧边栏宽度从120px线性降到0,flex布局自动计算剩余空间分配给中间区域,中间区域设置的transition会自动监听宽度变化完成平滑展开,和侧边栏动画完全同步
  • 所有动画由CSS原生驱动,不需要JS手动计算宽度,性能更好
  • 保留了原有中间区域hover放大的交互,不影响原有逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 19:03:50