第一章:Vue动画初探
为什么需要动画?
说实话,我刚开始做前端那会儿,也觉得动画就是个花架子。不就是让元素动一动嘛,能有什么实际价值?直到有一次,我负责一个后台管理系统,用户反馈说「点完按钮不知道有没有生效」——嗯,这就是没有动画的代价。
动画在UI里扮演的角色,比你想象的重要得多:
- 引导注意力:新内容出现时,动画能告诉用户「看这里」
- 解释变化:元素从A变到B,动画展示了「怎么变的」
- 提升感知性能:加载动画让用户觉得「没那么慢」
- 增加愉悦感:说白了,好看的动画让人心情好
我个人习惯把动画分成两类:功能性动画和装饰性动画。功能性动画解决「用户知不知道发生了什么」的问题,装饰性动画解决「用户觉得好不好看」的问题。先搞定前者,再追求后者。
Vue过渡系统概述
Vue的过渡系统,说白了就是一套帮你搞定元素「进场」和「离场」的机制。你想想看,一个组件从无到有,或者从有到无,中间发生了什么?Vue帮你管理这个过程。
核心就三个东西:
<Transition>:单个元素的进入/离开动画<TransitionGroup>:列表的增删移动动画<KeepAlive>:组件缓存,配合过渡使用效果更佳
我在项目中遇到过最典型的场景:弹窗组件。没有过渡时,弹窗「啪」一下出现,用户会被吓一跳。加了淡入淡出后,体验立马不一样了。
Vue的过渡系统不依赖任何第三方库。你完全可以只用CSS就做出不错的动画效果。当然,想玩更复杂的,可以搭配GSAP或Anime.js。
CSS过渡与动画基础回顾
在深入Vue之前,咱们先快速过一遍CSS里的动画基础。这部分如果你已经熟悉,可以跳过。但我建议你还是看一眼,因为Vue的过渡类名和CSS的过渡属性是直接对应的。
CSS Transition
CSS过渡,就是从一个状态平滑变到另一个状态。比如鼠标悬停时改变颜色:
.box {
background-color: blue;
transition: background-color 0.3s ease;
}
.box:hover {
background-color: red;
}
这里要注意几个属性:
| 属性 | 作用 | 常用值 |
|---|---|---|
transition-property |
指定哪些属性要过渡 | all, opacity, transform |
transition-duration |
过渡时长 | 0.3s, 500ms |
transition-timing-function |
缓动函数 | ease, linear, cubic-bezier() |
transition-delay |
延迟开始 | 0.1s |
我曾经踩过一个坑:给 all 属性加过渡,结果页面里所有变化都变慢了。后来我改成只给 opacity 和 transform 加过渡,性能立马好了很多。记住,不要滥用 all。
CSS Animation
CSS动画比过渡更强大。它可以定义多个关键帧,实现更复杂的动效:
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.box {
animation: fadeIn 0.5s ease forwards;
}
关键帧动画的几个核心属性:
animation-name:指定 @keyframes 的名字animation-duration:动画时长animation-timing-function:缓动函数animation-iteration-count:播放次数,infinite表示无限循环animation-direction:播放方向,alternate可以来回播放animation-fill-mode:动画结束后的状态,forwards保持最后一帧
我个人习惯用 animation-fill-mode: forwards,这样动画结束后元素会保持在最终状态,不会「跳回」初始位置。这个小细节,能避免很多奇怪的闪烁问题。
Vue过渡类名机制
Vue的过渡系统,本质上就是在元素插入或移除时,自动给元素添加/移除特定的CSS类名。你只需要写好这些类名对应的样式,剩下的交给Vue。
以进入动画为例,Vue会依次添加三个类名:
v-enter-from:进入的起始状态(比如 opacity: 0)v-enter-active:进入的过渡状态(比如 transition: opacity 0.3s)v-enter-to:进入的结束状态(比如 opacity: 1)
离开动画同理,对应 v-leave-from、v-leave-active、v-leave-to。
你想想看,Vue帮你做了最麻烦的部分——在正确的时机添加和移除类名。你只需要关心「开始长什么样」和「结束长什么样」,中间的过渡效果交给CSS。
一个最简单的例子
来看一个完整的例子,感受一下Vue过渡到底有多简单:
<template>
<button @click="show = !show">切换</button>
<Transition>
<p v-if="show">Hello Vue Transition!</p>
</Transition>
</template>
<script setup>
import { ref } from 'vue'
const show = ref(true)
</script>
<style>
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
</style>
这段代码做了什么?
- 点击按钮切换
show的值 - Vue检测到
v-if变化,自动包裹<Transition>的逻辑 - 元素出现时,添加
v-enter-from→v-enter-active→v-enter-to - 元素消失时,添加
v-leave-from→v-leave-active→v-leave-to - CSS过渡让透明度从0变到1,再从1变到0
就这么简单。你不需要写任何JavaScript来控制动画的启停,Vue全帮你搞定了。
如果你觉得 v- 前缀太通用,可以用 name 属性自定义前缀。比如 <Transition name="fade">,类名就变成 fade-enter-from、fade-enter-active 这样。我在项目中几乎每次都这么用,避免样式冲突。
小结
这一章我们聊了:
- 动画为什么重要——不只是好看,更是为了好用
- Vue过渡系统的三个核心组件
- CSS过渡和动画的基础知识
- Vue过渡类名的机制和用法
下一章,我们会深入 <Transition> 组件的各种用法,包括自定义类名、JavaScript钩子、以及和第三方动画库的集成。到时候我会分享一些我在实际项目中踩过的坑,保证有用。