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

Vue.js 使用v-if切换页面时部分CSS动画不生效如何解决

问题原因

你遇到的问题根源是Vue的DOM更新是批量异步执行的:当你切换page值回到dashboard页时,v-if创建DOM元素和:class绑定动画类的操作是在同一个更新批次完成的。浏览器会认为新创建的元素天生就带有动画类,CSS动画只会在类被主动添加到已有元素时触发,因此就出现了首次加载有动画、切走再回来无动画的问题。

修复方案(推荐:用Vue内置Transition组件)

Vue官方提供的过渡组件专门用来处理这类元素显隐动画场景,稳定性更高,也不需要手动控制类名时序。

修改后的HTML代码

<div id="app">
  <button @click="dashboardPageBtn" class="">Dashboard</button>
  <button @click="productsPageBtn">Products</button>

  <!-- 加Transition包裹层 -->
  <transition name="fade-up" mode="out-in">
    <div v-if="page == 'dashboard-page'" id="dashboard">
        <h1 class="top-menu-header-title">Dashboard</h1>
    </div>
    <div v-if="page == 'products-page'" id="product">
      <div class="mt-10 text-4xl mb-10">
        <h1 class="top-menu-header-title">Test</h1>
      </div>
    </div>
  </transition>
</div>

修改后的CSS代码

把原来手动写的动画类改成Transition对应的内置类名即可,JS代码不需要改动:

/* 进入动画激活态配置 */
.fade-up-enter-active {
    animation-duration: 1s;
    animation-fill-mode: both;
    -webkit-animation-duration: 1s;
    -webkit-animation-fill-mode: both;
    animation-name: fadeInUp;
    -webkit-animation-name: fadeInUp;
}
/* 进入动画初始状态 */
.fade-up-enter-from {
    opacity: 0;
}

/* 内容上移渐入动画 */
@keyframes fadeInUp {
    from {
        transform: translate3d(0,40px,0)
    }
    to {
        transform: translate3d(0,0,0);
        opacity: 1
    }
}
@-webkit-keyframes fadeInUp {
    from {
        transform: translate3d(0,40px,0)
    }
    to {
        transform: translate3d(0,0,0);
        opacity: 1
    }
}

备选方案(不改动现有结构的快速修复)

如果你不想用Transition组件,也可以通过拆分更新批次的方式解决:新增一个控制动画类的变量,切换页面时先重置变量,等DOM更新完成后再打开动画触发开关:

修改后的JS代码

var app = new Vue({
  el: "#app",
  data() {
    return {
      page: "dashboard-page",
      headerTitle: "Dashboard",
      showAnim: false // 新增动画控制变量
    };
  },
  methods: {
    productsPageBtn(e) {
      this.showAnim = false
      this.page = "products-page";
      this.headerTitle = "Products";
      // 等DOM更新完成后再触发动画
      this.$nextTick(() => {
        this.showAnim = true
      })
    },
    dashboardPageBtn() {
      this.showAnim = false
      this.page = "dashboard-page";
      this.headerTitle = "Dashboard";
      this.$nextTick(() => {
        this.showAnim = true
      })
    }
  }
});

修改HTML的class绑定

<div v-if="page == 'dashboard-page'" id="dashboard" :class="{'content-fade-up-animation' : showAnim}">
    <h1 class="top-menu-header-title">Dashboard</h1>
</div>

<div v-if="page == 'products-page'" id="product" :class="{'content-fade-up-animation' : showAnim}">
  <div class="mt-10 text-4xl mb-10">
    <h1 class="top-menu-header-title">Test</h1>
  </div>
</div>

CSS不需要改动,这种方式也能保证每次元素渲染完成后才添加动画类,触发动画效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 22:48:01