- Vue3中,transition拥有八个生命周期钩子函数,分别控制元素进入之前、进入过程中、进入之后、进入被打断时,离开之前、离开过程中、离开之后、离开被打断时所执行的回调
生命周期钩子函数名 | 执行时机 |
---|---|
@before-enter | 元素进入之前 |
@enter | 进入过程中 |
@after-enter | 进入之后 |
@enter-cancelled | 进入被打断时 |
@before-leave | 离开之前 |
@leave | 离开过程中 |
@after-leave | 离开之后 |
@leave-cancelled | 离开被打断时 |
- 与其他生命周期钩子不同的是,transition动画组件的生命周期钩子并不直接写在脚本中,而是通过类似定义事件的方式(参考@click)来执行对应回调
- 所有的生命周期钩子函数都接收一个el:Element的参数表示当前正在执行动画的元素的真实DOM结构。此外@enter和@after额外接收一个done:Function回调函数,当回调被调用时表示进入/离开动作全部完成,接下来才执行after-enter或after-leave函数,如果不写的话Vue将根据动画/过渡持续时间来判断何时结束(用不用要随机应变,路不能走窄了)
- @leave-cancelled只能在v-show中使用,写在v-if控制的元素中不起作用
完整代码:
动画组件生命周期钩子
<template>
<div class="card">
<transition
name="box"
@before-enter="beforeEnter"
@enter="enterActive"
@after-enter="afterEnter"
@enter-cancelled="enterCancel"
@before-leave="beforeLeave"
@leave="leaveActive"
@after-leave="afterLeave"
@leave-cancelled="leaveCancel"
>
<A v-if="flag"></A>
</transition>
<button @click="flag = !flag">显示/隐藏组件</button>
</div>
</template>
<script setup lang="ts">
import 'animate.css'
import { ref, reactive } from 'vue'
import A from './components/A.vue'
let flag = ref(true)
const beforeEnter = (el: Element) => {
console.log('进入之前')
}
const enterActive = (el: Element, done: Function) => {
console.log('进入过程中')
// 三秒后才执行afterEnter
setTimeout(() => {
done()
}, 3000)
}
const afterEnter = (el: Element) => {
console.log('进入动作完成')
}
const enterCancel = (el: Element) => {
console.log('进入动作被打断')
}
// 离开的代码同上,此处不再示范
const beforeLeave = () => {
console.log('离开之前')
}
const leaveActive = (el: Element, done: Function) => {
console.log('离开过程中')
setTimeout(() => {
done()
}, 3000)
}
const afterLeave = () => {
console.log('离开动作完成')
}
const leaveCancel = () => {
console.log('离开动作被打断')
}
</script>
<style scoped>
.card {
border: 1px solid black;
}
.background {
width: 200px;
height: 200px;
background-color: red;
}
.box-enter-from {
width: 0;
height: 0;
}
.box-enter-active {
transition: all 1s ease;
}
.box-enter-to {
width: 200px;
height: 200px;
transform: rotate(-360deg);
}
.box-leave-from {
width: 200px;
height: 200px;
}
.box-leave-active {
transition: all 1s ease;
}
.box-leave-to {
width: 0;
height: 0;
transform: rotate(360deg);
}
</style>
GSAP:GSAP是一个动画库,可以在脚本中直接写入动画,需要注意的是通过这种方式设计动画会覆盖CSS原有的样式
示例:
简单GSAP
<template>
<div class="card">
<transition
name="box"
@before-enter="beforeEnter"
@enter="enterActive"
@leave="leaveActive"
>
<A v-if="flag"></A>
</transition>
<button @click="flag = !flag">显示/隐藏组件</button>
</div>
</template>
<script setup lang="ts">
import 'animate.css'
import gsap from 'gsap'
import { ref, reactive } from 'vue'
import A from './components/A.vue'
let flag = ref(false)
const beforeEnter = (el: Element) => {
gsap.set(el, {
width: 0,
height: 0,
})
}
const enterActive = (el: Element, done: GSAPCallback) => {
gsap.to(el, {
width: 200,
height: 200,
onComplete: done,
})
}
const leaveActive = (el: Element, done: GSAPCallback) => {
gsap.to(el, {
width: 0,
height: 0,
})
}
</script>
<style scoped>
.card {
border: 1px solid black;
}
</style>