vue动画实现原理
Vue 动画的实现原理
Vue 的动画系统基于 CSS 过渡和动画,结合 Vue 的响应式特性,通过动态添加/移除 CSS 类来实现动画效果。核心机制分为以下几个部分:
过渡类名的自动添加
当元素插入或移除时,Vue 会根据过渡状态自动添加对应的 CSS 类名。例如,一个元素进入时,会依次添加以下类:
v-enter:进入动画的初始状态v-enter-active:进入动画的激活状态(定义过渡时长和曲线)v-enter-to:进入动画的结束状态(2.1.8+ 版本)
<transition name="fade">
<div v-if="show">内容</div>
</transition>
对应的 CSS 示例:
.fade-enter {
opacity: 0;
}
.fade-enter-active {
transition: opacity 0.5s;
}
.fade-enter-to {
opacity: 1;
}
JavaScript 钩子函数
Vue 提供 JavaScript 钩子函数,允许在动画生命周期中执行自定义逻辑:
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@enter-cancelled="enterCancelled"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave"
@leave-cancelled="leaveCancelled"
>
<!-- 内容 -->
</transition>
钩子函数接收元素对象和回调函数,可用于实现复杂的动画逻辑(如 Velocity.js 或 GSAP)。
列表过渡(<transition-group>)
对于动态列表的动画,Vue 提供 <transition-group> 组件,通过 v-for 渲染列表项时,每个元素会独立触发动画。关键点包括:
- 需要设置
tag属性指定包裹元素的标签 - 每个子元素必须有唯一的
key - 内部使用 FLIP 动画技术优化性能
<transition-group name="list" tag="ul">
<li v-for="item in items" :key="item.id">
{{ item.text }}
</li>
</transition-group>
状态过渡
对于数据变化驱动的动画(如数字递增、颜色渐变),Vue 推荐使用第三方库如 Tween.js 或自定义插值函数:
new Vue({
data: { tweenedNumber: 0 },
watch: {
number(newVal) {
TweenLite.to(this.$data, 0.5, { tweenedNumber: newVal });
}
}
})
底层实现细节
- 虚拟 DOM 协调:Vue 在虚拟 DOM 更新时检测元素的插入/移除,触发过渡逻辑。
- 异步队列:动画完成后通过
requestAnimationFrame和nextTick确保时序正确。 - CSS 嗅探:自动检测 CSS 过渡/动画持续时间,避免 JavaScript 钩子过早触发。
通过组合这些机制,Vue 实现了声明式、高性能的动画系统,开发者无需直接操作 DOM 即可完成复杂动效。







