CSS transition 和 @keyframes 覆盖 90% 动画需求,transition 适用于有明确起止状态的显隐/切换场景,需配合 class 切换与 v-if/v-show;@keyframes 适合自驱动循环动画;transition-group 管理列表增删动画;Animate.css 可快速接入预设动画,但需注意平台兼容性与合理使用边界。

直接用 CSS transition 和 @keyframes 就能覆盖 90% 的日常需求,不需要引入动画库或调用 uni.createAnimation —— 后者只在需要精确控制帧、链式触发、或响应触摸位移时才必要。
transition 控制显隐/状态切换动画
适用于按钮点击反馈、抽屉展开、弹窗入场、开关切换等「有明确起止状态」的场景。核心是靠 class 切换触发动画,不是靠 JS 手动逐帧操作。
- 必须配合
v-if或v-show使用,单独改 style 不会触发transition类名钩子 - 类名命名要统一:
.fade-enter-active/.fade-leave-active对应过渡过程,.fade-enter/.fade-leave-to对应起始/结束样式 - 慎用
all:写成transition: all 0.3s容易意外带动 layout 属性(如height、margin),引发重排;推荐明确写transition: opacity 0.3s, transform 0.3s - 移动端上,
transform和opacity是唯二被 GPU 加速的属性,其他如background-color、width会掉帧
@keyframes 实现循环/多阶段动画
适合 loading 指示器、呼吸灯效果、进度条流动、图标微动等「不依赖数据状态、自驱动」的动画。和 transition 本质不同:它是时间轴驱动,不是状态驱动。
- 必须用
animation属性绑定,例如animation: bounce 1s ease-in-out infinite - 不要在
@keyframes里写display: none—— 浏览器不支持动画 display,要用opacity: 0+visibility: hidden组合替代 - 小程序平台对
animation-fill-mode支持不一致,forwards在某些微信版本下失效,结尾态建议用 JS 补一手 class - 避免嵌套过深的
@keyframes:比如同时定义 5 个不同元素的独立 keyframes,在低端安卓机上可能卡顿
transition-group 管理列表项增删动画
当你要给 v-for 渲染的列表项加「逐个入场」「滑动删除」效果时,<transition-group> 是唯一干净解法。它会给每个节点自动添加唯一 key 并注入生命周期类名。
立即学习“前端免费学习笔记(深入)”;
- 必须带
tag属性,否则默认渲染为span,可能破坏布局流(比如你期望它是view) - 不能直接在
<transition-group>上写class,动画样式要写在内部元素上,例如.list-item-enter-active - 移动端列表滚动中插入新项时,动画容易跳帧 —— 建议加
will-change: transform提前提示浏览器启用硬件加速 - 如果列表项高度不固定(比如含文字折行),
height过渡会失效,改用max-height+overflow: hidden模拟
用 Animate.css 快速接入预设动画
当你需要「抖动提醒」「弹跳确认」「翻转卡片」这类有情绪表达的动画,又不想手写 keyframes,引入 Animate.css 是最快路径。但它不是万能胶,得知道边界在哪。
- 必须在
App.vue全局引入,不能按需 import 到单个组件 —— 小程序端不支持动态加载 CSS - 动画类名是原子化的,例如
animate__bounceIn,但默认带animate__animated基础类,漏写就无效 - 部分动画(如
animate__flip)依赖perspective,若父容器没设transform-style: preserve-3d,在 iOS 微信里会降级为平面翻转 - 别滥用
infinite:像animate__pulse默认无限循环,实际使用时务必加animation-iteration-count: 1覆盖,否则用户无法聚焦内容
真正难的不是写出动画,而是判断该不该动、动多少、在哪一帧停住。比如一个表单提交按钮,按下时缩放 95% 就够了,没必要加旋转+抖动+渐变色 —— 用户要的是确定性反馈,不是马戏团。


















