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
相关产品推荐
相关产品推荐

