Vue列表过渡用<transition-group>实现增删及排序动画,需唯一key和move类;状态过渡用<transition>控制单元素显隐,支持CSS/JS钩子;优化建议:用transform/opacity、禁用冗余move、语义化name。

Vue.js 的列表过渡和状态过渡动画,核心在于利用 <transition> 和 <transition-group> 组件配合 CSS 类名或 JavaScript 钩子,让 DOM 元素的进入、离开、排序变化具备可感知的动效。关键不是堆砌动画,而是让过渡自然贴合用户操作意图。
用 <transition-group> 实现列表项增删动画
<transition-group> 是专为列表设计的过渡包装器,它会为每个子元素(如 v-for 渲染的 <li>)独立添加/移除 CSS 过渡类,同时支持列表重排动画(通过 move 钩子)。
- 必须为每个列表项设置唯一的
key,否则 Vue 无法追踪节点身份,过渡将失效 - 默认渲染为
<span>,可用tag属性指定真实容器(如tag="ul") - 进入过程触发
v-enter→v-enter-active→v-enter-to;离开过程触发v-leave→v-leave-active→v-leave-to - 添加
move类(如.list-move)可定义列表顺序变化时的位移过渡,推荐用transform: translateX()配合transition实现平滑拖拽感
用 <transition> 控制单个状态切换动画
当需要对布尔值控制的显示/隐藏区域(如模态框、折叠面板、加载提示)添加动画时,<transition> 更合适。它不处理多个子节点,只关注包裹内容的整体状态变化。
- 内部只能有一个根节点(或用
<template>包裹多个节点,但需确保最终渲染为单个元素) - 常用场景:点击按钮显示弹窗,用
v-if控制显隐,<transition name="fade">就能启用淡入淡出 - 可通过
appear属性启用初始渲染动画;用mode(如"out-in")避免新旧元素同时存在造成的布局冲突 - 若 CSS 动画不够灵活(比如需要逐帧控制),可使用 JavaScript 钩子:
@before-enter、@enter、@leave等,配合done回调手动控制完成时机
动画性能与细节优化建议
流畅的过渡体验依赖于合理的实现方式,而非复杂效果。
立即学习“前端免费学习笔记(深入)”;
- 优先使用
transform和opacity触发 GPU 加速,避免直接动画height或margin(会触发重排) - 列表项较多时,禁用
move过渡或限制动画持续时间(如.list-move { transition-duration: 0.2s; }),防止卡顿 - 用
duration属性精确控制 JS 钩子动画时长,或在 CSS 中统一定义transition-property和transition-duration - 为不同状态定义语义化 name(如
name="slide-fade"),生成的类名更易维护(slide-fade-enter-active)
常见问题快速排查
动画不生效?大概率是这几个地方出了问题:
-
key值重复或未设置 → 列表项无法被单独识别 - 用
v-show替代v-if→<transition>不支持v-show的切换(它只是切display) - CSS 类名拼写错误或未加
!important(仅当被其他样式覆盖时才需) - 父容器设置了
overflow: hidden却没预留足够空间 → 动画中元素被裁剪


















