第 16 章:动画
学习目标
- 用
<Transition>包裹单元素 - 用
<TransitionGroup>做列表过渡 - 配合 CSS 类名 / keyframes 实现动画
- 避坑:display:none 与动画冲突
一、单元素过渡
vue
<template>
<button @click="show = !show">toggle</button>
<Transition name="fade">
<p v-if="show">Hello</p>
</Transition>
</template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
</style>类名时序:
v-enter-from进入前v-enter-active进入过程v-enter-to进入完成- 离开:
v-leave-from→v-leave-active→v-leave-to
⚠️ 坑 1:如果元素上有
display: none,动画不会触发。
二、keyframes 动画
css
.zoom-enter-active {
animation: zoom 0.3s;
}
.zoom-leave-active {
animation: zoom 0.3s reverse;
}
@keyframes zoom {
from { transform: scale(0); }
to { transform: scale(1); }
}三、列表过渡
vue
<TransitionGroup name="list" tag="ul">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</TransitionGroup>css
.list-enter-active, .list-leave-active {
transition: all 0.3s;
}
.list-enter-from { opacity: 0; transform: translateX(30px); }
.list-leave-to { opacity: 0; transform: translateX(-30px); }
.list-move { transition: transform 0.3s; }⚠️ 坑 2:列表项必须带
:key,否则 move 动画不生效。
四、JS 钩子
vue
<Transition
:css="false"
@before-enter="onBeforeEnter"
@enter="onEnter"
@leave="onLeave"
>
<p v-if="show">Hi</p>
</Transition>ts
const onEnter = (el: Element, done: () => void) => {
const animate = (el as HTMLElement).animate(
[{ opacity: 0 }, { opacity: 1 }],
{ duration: 300 },
)
animate.onfinish = done
}五、appear 首次加载
vue
<Transition name="fade" appear>
<p>页面打开就出现</p>
</Transition>六、mode 控制时机
vue
<Transition name="fade" mode="out-in">
<p v-if="ok">A</p>
<p v-else>B</p>
</Transition>| mode | 行为 |
|---|---|
| 默认 | 同时进出,会重叠 |
out-in | 先走再进 |
in-out | 先进再走 |
七、实战:折叠面板
vue
<template>
<button @click="open = !open">{{ open ? '收起' : '展开' }}</button>
<Transition name="collapse">
<div v-show="open" class="content">
<slot />
</div>
</Transition>
</template>
<style>
.collapse-enter-active, .collapse-leave-active {
transition: max-height 0.3s, opacity 0.3s;
overflow: hidden;
}
.collapse-enter-from, .collapse-leave-to {
max-height: 0;
opacity: 0;
}
.collapse-enter-to, .collapse-leave-from {
max-height: 500px;
opacity: 1;
}
</style>⚠️ 坑 3:
height: auto不能直接 transition,要用max-height撑开。
八、本章小结
| 类名 | 作用 |
|---|---|
-enter-from | 进入前 |
-enter-active | 进入过程 |
-enter-to | 进入完成 |
-leave-* | 离开对应 |
-move | 列表移动 |
动手练习
- 淡入淡出:按钮切换显示/隐藏,带过渡
- 列表动画:加 / 删 todo,带 move 动画
- 折叠面板:用 max-height 实现可展开内容
下一章:第 17 章:过渡 →