内置组件(上)—— Transition
本教程共 40 篇 · 第 32 篇 · 更新于 2026-07-29 · 约 8 分钟阅读
32. 内置组件(上)—— Transition
本节目标:学会用
<Transition>给元素和组件添加进入/离开动画,理解六种过渡类名和两种实现方式。
Transition 是什么
<Transition> 是 Vue 的内置组件,不需要 import 就能用。它负责在元素进入或离开 DOM 时自动添加过渡效果。
触发过渡的四种方式:
v-if条件渲染v-show条件显示<component :is>动态切换组件- 改变元素的
key属性
最简单的例子:
<button @click="show = !show">切换</button>
<Transition>
<p v-if="show">hello</p>
</Transition>
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
Tip
<Transition>只能包含一个根元素。如果内容是组件,那组件也只能有一个根元素。
六种过渡类名
元素进入和离开时,Vue 会自动添加/移除这些类名:
| 类名 | 阶段 | 时机 |
|---|---|---|
v-enter-from | 进入开始 | 插入前添加,插入后下一帧移除 |
v-enter-active | 进入过程 | 整个进入阶段,定义 duration、delay、easing |
v-enter-to | 进入结束 | 插入后下一帧添加,过渡完成后移除 |
v-leave-from | 离开开始 | 触发离开时立即添加,下一帧移除 |
v-leave-active | 离开过程 | 整个离开阶段,定义 duration、delay、easing |
v-leave-to | 离开结束 | 触发离开后下一帧添加,过渡完成后移除 |
v-enter-active 和 v-leave-active 最有用——它们让你分别定义进入和离开的缓动曲线。
命名过渡
默认类名以 v- 开头。如果想用自定义前缀,给 <Transition> 加 name 属性:
<Transition name="fade">
<p v-if="show">hello</p>
</Transition>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
命名过渡的好处是:同一个元素可以有多个过渡效果,通过不同的 name 切换。
CSS 过渡 vs CSS 动画
CSS 过渡(transition):需要触发事件(如 hover、类名变化),定义开始和结束状态。
CSS 动画(animation):可以自动播放,支持关键帧。
用 CSS 动画时,*-enter-from 不会在插入后立即移除,而是等 animationend 事件触发才移除:
<Transition name="bounce">
<p v-if="show">弹弹弹</p>
</Transition>
.bounce-enter-active {
animation: bounce-in 0.5s;
}
.bounce-leave-active {
animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
0% { transform: scale(0); }
50% { transform: scale(1.25); }
100% { transform: scale(1); }
}
自定义过渡类名
如果你想用第三方动画库(比如 Animate.css),可以通过 props 覆盖默认类名:
<Transition
enter-active-class="animate__animated animate__tada"
leave-active-class="animate__animated animate__bounceOutRight"
>
<p v-if="show">hello</p>
</Transition>
可用的 props:enter-from-class、enter-active-class、enter-to-class、leave-from-class、leave-active-class、leave-to-class。
同时使用过渡和动画
如果同一个元素上既有 CSS 动画又有 CSS 过渡(比如 Vue 控制的动画 + hover 时的过渡),你需要告诉 Vue 该监听哪种类型:
<Transition type="animation">
<!-- 只监听 animationend -->
</Transition>
嵌套过渡
<Transition> 的过渡类名只作用于直接子元素,但可以通过 CSS 选择器影响嵌套元素:
<Transition name="nested">
<div v-if="show" class="outer">
<div class="inner">Hello</div>
</div>
</Transition>
.nested-enter-active .inner,
.nested-leave-active .inner {
transition: all 0.3s ease-in-out;
}
.nested-enter-from .inner,
.nested-leave-to .inner {
transform: translateX(30px);
opacity: 0;
}
还可以加延迟实现错开动画:
.nested-enter-active .inner {
transition-delay: 0.25s;
}
Note嵌套过渡有个小坑:默认
<Transition>监听第一个transitionend事件来判断过渡结束。如果内部元素过渡时间更长,需要用duration属性显式指定总时长。
JavaScript Hooks
除了 CSS,你还可以用 JavaScript 控制过渡:
<Transition
@before-enter="onBeforeEnter"
@enter="onEnter"
@after-enter="onAfterEnter"
@enter-cancelled="onEnterCancelled"
@before-leave="onBeforeLeave"
@leave="onLeave"
@after-leave="onAfterLeave"
@leave-cancelled="onLeaveCancelled"
>
<p v-if="show">hello</p>
</Transition>
function onEnter(el, done) {
// 执行动画...
// 动画完成后调用 done()
// 如果配合 CSS,done 可以不调
done()
}
纯 JavaScript 过渡时,建议加 :css="false" 让 Vue 跳过 CSS 检测,提升性能:
<Transition :css="false" @enter="onEnter" @leave="onLeave">
Note
:css="false"时,done回调是必须的。不调的话过渡会立即完成。
过渡模式
默认情况下,进入和离开动画同时进行。有时候你想要”先出后进”的效果:
<Transition mode="out-in">
<button v-if="docState === 'saved'">编辑</button>
<button v-else-if="docState === 'edited'">保存</button>
<button v-else-if="docState === 'editing'">取消</button>
</Transition>
| 模式 | 效果 |
|---|---|
| 默认 | 进入和离开同时进行 |
out-in | 先离开,离开完成后再进入 |
in-out | 先进入,进入完成后再离开(少用) |
动态过渡
<Transition> 的 name 也可以是响应式的:
<Transition :name="transitionName">
<p v-if="show">hello</p>
</Transition>
根据状态切换不同的过渡效果。
初始渲染过渡
想让元素首次出现时也有过渡效果,加 appear 属性:
<Transition appear>
<p>hello</p>
</Transition>
性能建议
动画属性有性能差异:
| 推荐 | 避免 |
|---|---|
transform | height |
opacity | margin |
translate | width |
transform 和 opacity 不触发页面布局计算,浏览器还能 GPU 加速。height、margin 这些会触发重排,动画过程中页面会”抖”。
本节回顾
<Transition>在元素进入/离开 DOM 时自动添加过渡效果- 六种过渡类名:
enter-from、enter-active、enter-to、leave-from、leave-active、leave-to - 命名过渡用
name属性,类名前缀跟着变 - CSS 过渡用
transition,CSS 动画用@keyframes - JavaScript Hooks 适合复杂动画,配合 GSAP 等库使用
mode="out-in"实现先出后进- 动画属性优先选
transform和opacity