Vue 3的<Transition>和<TransitionGroup>是与响应式系统深度协同的动画调度机制,核心为状态感知、类名注入与生命周期钩子联动;前者精准控制单元素显隐,后者基于key追踪与FLIP技术实现列表增删移位动画,并依赖render阶段vnode比对与浏览器帧同步调度。

Vue 3 的 <Transition> 和 <TransitionGroup> 并非只是“加个 CSS 类”那么简单——它们是一套与响应式系统深度协同的动画调度机制,核心在于**状态感知 + 类名注入 + 生命周期钩子联动**。
Transition 如何精准控制单元素显隐动画
<Transition> 本质是一个“状态观察器”,它不直接操作 DOM,而是监听包裹内容的 v-if / v-show / 动态组件切换 触发时机,并在恰当节点注入预设类名:
- 当元素即将插入(
v-if从 false → true),依次添加:v-enter-from→v-enter-active→v-enter-to;动画结束后自动移除from和to类 - 当元素即将移除(
v-if从 true → false),先保留当前样式,再添加:v-leave-from→v-leave-active→v-leave-to;离开动画完成即销毁节点 - 若同时存在进入和离开(如 tab 切换),默认会并行执行;加
mode="out-in"可强制先离开、再进入,避免视觉重叠 - 类名前缀可自定义:通过
name="fade"生成fade-enter-active等,也可用enter-active-class等属性完全覆盖类名
TransitionGroup 怎样管理列表的增删移动动画
<TransitionGroup> 在 <Transition> 基础上扩展了key tracking + 位置映射 + FLIP 技术支持,专为列表设计:
详细的 Three.js 3D 图形参考,涵盖场景设置、相机、几何体、材质、光照、动画、控制器、加载器、数学工具和调试。
- 必须为每个子元素设置唯一且稳定的
:key(如item.id),Vue 才能识别哪些是新增、删除或位移的节点 - 新增项触发
enter类;删除项触发leave类;而 位置变化项自动触发v-move(需显式定义该类的 transition) - 内部使用 FLIP(First, Last, Invert, Play)策略:先记录旧位置 → 计算新位置 → 立即 invert(反向 transform)→ 播放 transition,实现平滑位移
-
tag属性指定外层容器类型(如tag="ul"),否则默认渲染为<span>,不符合语义化结构
动画与响应式系统的底层协同机制
过渡组件不是独立运行的,它深度依赖 Vue 3 的响应式更新流程:
立即学习“前端免费学习笔记(深入)”;
- 在
render阶段,<Transition>不生成真实 DOM,只返回一个“占位型 vnode”,其子节点由父级逻辑决定是否渲染 - 当响应式依赖变化触发 re-render,
patch过程中会比对前后 vnode 的 key 和存在状态,从而判定进入/离开/保持等动作 - 类名注入发生在
beforeMount和updated钩子之间,由renderer调度器统一控制时机,确保与浏览器重绘帧同步 - JavaScript 钩子(如
@before-enter)在对应类名添加前调用,可用于动态设置初始样式(如基于元素尺寸计算 transform)
性能优化的关键细节
真正影响动画流畅度的,往往不是 CSS 写法,而是这些底层约束:
-
v-move必须使用transform和opacity,避免触发布局(layout)或绘制(paint);用will-change: transform提前提醒浏览器优化 - 列表项频繁增删时,建议配合
key使用 stable ID(而非 index),防止 key 复用导致动画错乱 - 过渡动画应尽量控制在 200–500ms,过长易被用户感知为卡顿,过短则失去引导作用
- 若动画逻辑复杂,可用
appear属性启用首次挂载动画,避免首屏闪烁

















