1、动画基础:Vue过渡系统概述、CSS过渡与动画的区别、使用<transition>组件包裹元素、name属性与类名约定
1.1 Vue过渡系统:到底解决了什么问题?
说实话,我刚接触Vue动画时,第一反应是:「直接用CSS写动画不就行了?干嘛还要学一套新东西?」
后来在项目中踩了坑才明白——Vue过渡系统解决的核心问题,是元素进入/离开DOM时的状态管理。
你想想看,一个普通的CSS动画,只能控制元素「已经在页面上」时的表现。但Vue的v-if或v-show切换时,元素是动态创建和销毁的。这时候,你需要在元素插入前、插入瞬间、离开前、离开后这四个时间点,精准地控制样式。
手动去监听这些时机?太累了。Vue的<transition>组件就是来干这个的。
核心要点:Vue过渡系统本质上是「状态机 + CSS类名切换」的封装。它不创造新的动画能力,而是帮你管理动画的触发时机。
1.2 CSS过渡 vs CSS动画:别再傻傻分不清
很多初学者会把这两个概念混为一谈。我刚开始带团队时,就发现有人用animation去实现一个简单的淡入淡出,结果代码写得很复杂。
咱们来拆开看:
| 对比维度 | CSS过渡(transition) | CSS动画(animation) |
|---|---|---|
| 触发方式 | 需要状态变化(如hover、类名切换) | 可自动播放,无需外部触发 |
| 中间状态 | 只有开始和结束两个状态 | 可通过@keyframes定义多个关键帧 |
| 循环能力 | 不支持循环 | 支持无限循环 |
| 控制粒度 | 粗粒度,只能控制整体变化 | 细粒度,可控制每一帧 |
| 适用场景 | 简单的淡入淡出、位移、缩放 | 复杂的逐帧动画、循环动效 |
我的建议是:能用transition解决的,就别用animation。前者更轻量,性能也更好。只有当你需要「弹跳效果」、「逐帧播放」或「无限循环」时,才考虑animation。
小技巧:Vue的<transition>组件默认使用CSS过渡。如果你想用CSS动画,需要在类名里写animation属性。两者可以混用,但我个人不建议——容易搞混触发时机。
1.3 使用<transition>组件:最简单的入门姿势
直接上代码。这是最基础的使用方式:
<template>
<button @click="show = !show">切换</button>
<transition name="fade">
<p v-if="show">Hello, Vue 动画!</p>
</transition>
</template>
<script setup>
import { ref } from 'vue'
const show = ref(true)
</script>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
这段代码做了什么事?说白了就是:当show从true变成false时,Vue会自动给元素添加fade-leave-active和fade-leave-to类名;反之则添加fade-enter-active和fade-enter-from。
嗯,这里要注意:<transition>只能包裹单个子元素。如果你有多个元素需要同时动画,得用<transition-group>,这个后面章节会讲。
我曾经踩过的坑:<transition>不能直接包裹v-show控制的多个元素。如果你用v-show,动画只在第一次渲染时生效。后来我改用v-if + key属性才解决。
1.4 name属性与类名约定:Vue动画的命名规则
你注意到上面代码里的name="fade"了吗?这个name属性,就是Vue过渡系统的「命名空间」。
Vue内部有一套固定的类名约定:
- 进入动画:
{name}-enter-from:进入开始状态{name}-enter-active:进入进行中状态{name}-enter-to:进入结束状态
- 离开动画:
{name}-leave-from:离开开始状态{name}-leave-active:离开进行中状态{name}-leave-to:离开结束状态
如果你不设置name属性,默认值是v。也就是说,类名会变成v-enter-from、v-enter-active……
我个人习惯:每个<transition>都显式设置name。哪怕只有一个动画,也写上名字。为什么?因为项目大了以后,你根本记不住哪个v-对应哪个组件。命名清晰,维护起来才不痛苦。
记住这个规律:
enter-from + enter-active → 元素出现
leave-from + leave-active → 元素消失
enter-to 和 leave-to 是结束状态,通常和from相反。
1.5 实战中的避坑指南
最后分享几个我实际项目中遇到的坑:
- 动画不生效? 先检查
name属性是否和CSS类名匹配。我犯过最蠢的错误是CSS里写fade-,但模板里写name="fade"——看起来没错对吧?结果发现CSS里少写了一个字母。 - 动画闪烁? 通常是
enter-from和元素初始样式冲突。解决办法:在enter-from里显式覆盖初始样式。 - 动画卡顿? 别用
display: none做动画。Vue的v-if本身就是操作display,你再叠加一个display动画,浏览器会懵。
我的调试习惯:在浏览器开发者工具里,勾选「:hov」状态,手动添加.fade-enter-active类名,看看动画是否正常。如果手动添加能生效,那就是Vue的时机问题;如果不生效,那就是CSS写错了。
好了,这一章的内容就到这里。记住:Vue过渡系统不复杂,核心就是6个类名 + 1个name属性。把基础打牢,后面学<transition-group>和JS钩子函数时,你会觉得特别顺畅。