简述
Transition组件是Vue3提供的一个内置组件,无须注册,帮助你快速实现基于状态变化的过渡和动画效果. 当然, 过渡和动画效果需要你在css或借助第三方库实现. 以下是需要在css使用的默认六个类名:
-
v-enter-from
: 进入动画的起始状态. 此类名会在元素插入DOM前添加, 插入完成后下一帧移除 -
v-enter-active
: 进入动画的生效状态. 此类名将存在于整个动画阶段。在元素被插入之前添加,在过渡或动画完成之后移除 -
v-enter-to
: 进入动画的结束状态. 在元素插入完成后的下一帧被添加 ,在过渡或动画完成之后移除 -
v-leave-from
: 离开动画的起始状态. 此类名在离开过渡效果被触发时立即添加,在下一帧被移除 -
v-leave-active
: 离开动画的生效状态. 此类名将存在于整个动画阶段, 在离开过渡效果被触发时立即添加,在过渡或动画完成之后移除 -
v-leave-to
: 离开动画的结束状态. 在一个离开动画被触发后的下一帧被添加, 在过渡或动画完成之后移除
基础用法
淡入淡出效果
<button @click="show = !show">Toggle</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;
}
自定义类名前缀
<Transition name="fade">
...
</Transition>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
首次渲染执行过渡
appear默认是false, 开启后渲染时就会执行过渡效果
<Transition appear>
...
</Transition>
元素或组件间切换
1. 默认进入和离开的元素的动画是同时进行的
<Transition>
<button v-if="docState === 'saved'">Edit</button>
<button v-else-if="docState === 'edited'">Save</button>
<button v-else-if="docState === 'editing'">Cancel</button>
</Transition>
2. 使用过渡模式
<Transition mode="out-in">
...
</Transition>
进阶用法
结合CSS animation
<Transition name="bounce">
<p v-if="show" style="text-align: center;">
Hello here is some bouncy text!
</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);
}
}
使用第三方库动画
<Transition
enter-active-class="animate__animated animate__tada"
leave-active-class="animate__animated animate__bounceOut"
>
<p v-if="show">Animate.css 动画</p>
</Transition>
<!-- 在项目中安装 -->
<!-- npm install animate.css -->
// main.js
import 'animate.css'
可复用的过渡效果
<!-- MyTransition.vue -->
<script>
// JavaScript 钩子逻辑...
</script>
<template>
<!-- 内置的 Transition 组件 -->
<Transition
name="my-transition"
@enter="onEnter"
@leave="onLeave">
<slot></slot>
</Transition>
</template>
<style>
<!--
注意:避免在这里使用 <style scoped>
因为那不会应用到插槽内容上
-->
</style>
<MyTransition>
<div v-if="show">Hello</div>
</MyTransition>
Transition 钩子函数
<Transition
@before-enter="onBeforeEnter"
@enter="onEnter"
@after-enter="onAfterEnter"
@enter-cancelled="onEnterCancelled"
@before-leave="onBeforeLeave"
@leave="onLeave"
@after-leave="onAfterLeave"
@leave-cancelled="onLeaveCancelled"
>
<div v-if="show">JavaScript 钩子控制</div>
</Transition>
import { ref } from 'vue'
const show = ref(true)
function onBeforeEnter(el) {
console.log('元素进入前', el)
}
function onEnter(el, done) {
// 使用 GSAP 等库实现复杂动画
const animation = gsap.to(el, {
duration: 1,
opacity: 1,
y: 0,
onComplete: done
})
// 如需取消动画,调用done
// done(false)
}
function onAfterEnter(el) {
console.log('进入动画完成')
}
注意事项
-
使用Transition组件时,注意保证只有一个根节点,否则过渡或动画将不会生效
-
节点层级尽量不要过深,因为Transition只会监听第一层级的节点的事件来判断过渡是否结束,此时可借助duration属性来指定过渡结束时间
// 总的时间应该与内部元素过渡时间匹配 <Transition :duration="550">...</Transition>
性能优化
-
避免过度使用
-
制作动画应慎重使用height、margin等会影响DOM布局的属性,尽可能使用不会每一帧触发css布局重新计算的属性,如transform、opacity等.
-
优先使用CSS动画, 其性能优于JavaScript动画
总结
<Transiton> 是Vue3实现过渡和动画效果的强大工具, 通过它不需要手动操作dom即可实现过渡、动画,当然也支持JavaScript操作, 适应不同复杂场景的需求.