Vue 3 过渡动画实战:用 Transition 与 TransitionGroup 做进出场和列表动画
test12026-09-241 次阅读
单元素进出场:Transition
Vue 内置的 <Transition> 组件会在元素插入、移除时自动切换一组 CSS 类(v-enter-from、v-enter-active、v-leave-to 等),不需要任何 JS 动画库。只要把需要做动画的元素包进 <Transition>,并用 v-if 控制显隐即可。
<template>
<button @click="show = !show">切换</button>
<Transition name="fade">
<p v-if="show">一段会淡入淡出的文字</p>
</Transition>
</template>
<script setup>
import { ref } from "vue";
const show = ref(true);
</script>
<style>
.fade-enter-active,
.fade-leave-active { transition: opacity 0.3s ease; }
.fade-enter-from,
.fade-leave-to { opacity: 0; }
</style>
name="fade" 决定了类名前缀,Vue 会自动拼接 enter-from、enter-active、enter-to 三阶段;leave 同理。想做位移就在对应类里写 transform。
列表动画:TransitionGroup
渲染 v-for 列表时,用 <TransitionGroup> 可以分别给"新增、删除、移动"的节点加动画,移动动画依靠 FLIP 技术实现,几乎零成本。注意它默认不会渲染包裹元素,需要指定 tag。
<template>
<TransitionGroup name="list" tag="ul">
<li v-for="item in items" :key="item.id">
{{ item.text }}
<button @click="remove(item.id)">删除</button>
</li>
</TransitionGroup>
</template>
<script setup>
import { ref } from "vue";
const items = ref([
{ id: 1, text: "任务一" },
{ id: 2, text: "任务二" },
]);
function remove(id: number) {
items.value = items.value.filter((i) => i.id !== id);
}
</script>
<style>
.list-enter-active,
.list-leave-active { transition: all 0.3s ease; }
.list-enter-from,
.list-leave-to { opacity: 0; transform: translateX(20px); }
.list-move { transition: transform 0.3s ease; }
</style>
用 JS 钩子接管复杂动画
当 CSS 不够用时,Transition 支持 @before-enter、@enter、@leave 钩子,在里面调用 Web Animations API 或第三方动画库。钩子里调用 done() 告知 Vue 动画结束,避免提前移除节点。
<Transition @enter="onEnter" @leave="onLeave" :css="false">
<div v-if="show" class="box">弹层</div>
</Transition>
<script setup>
function onEnter(el: Element, done: () => void) {
(el as HTMLElement).animate(
[{ transform: "scale(0.8)", opacity: 0 }, { transform: "scale(1)", opacity: 1 }],
{ duration: 250 }
).onfinish = done;
}
function onLeave(el: Element, done: () => void) {
(el as HTMLElement).animate(
[{ opacity: 1 }, { opacity: 0 }],
{ duration: 200 }
).onfinish = done;
}
</script>
实践要点
- 列表动画必须给 v-for 的每一项加稳定且唯一的 key,否则移动动画会错乱。
- 纯显隐用 CSS 类即可;需要物理动画或结合动画库时再用 JS 钩子,并设 :css="false" 关闭 CSS 检测。
- 离开动画期间节点仍占位置,长列表频繁增删时留意性能,必要时对容器做 contain 优化。
T
test1
文章作者
单元素进出场:Transition Vue 内置的 <Transition> 组件会在元素插入、移除时自动切换一组 C...
- 分类
- 技术
- 发布时间
- 2026-09-24
- 字数
- 约 2407 字
- 阅读
- 1 次
