解决的问题
为组件的出现、消失添加过渡的东西效果
工作原理
- 当 DOM 元素被挂载时,将动效附加到该 DOM 元素上;
- 当 DOM 元素被卸载时,不要立即卸载 DOM 元素,而是等到附加到该 DOM 元素上的动效执行完成后再卸载它。
使用原生dom的实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/@vue/reactivity@3.0.5/dist/reactivity.global.js"></script>
<title>Document</title>
<style>
#div {
position: relative;
width: 100px;
height: 100px;
border: 1px solid black
}
.enter-from {
transform: translateX(200px);
}
.enter-active {
transition: all ease-in 3s;
}
.enter-to {
transform: translateX(0);
}
</style>
</head>
<body>
<div id="div"></div>
</body>
<script>
let div = document.getElementById("div")
enterAnimation(div)
div.addEventListener('click',()=>{
outerAnimation(div)
})
function enterAnimation(div) {
div.classList.add('enter-from')
div.classList.add('enter-active')
// 下一帧,再执行动画的过渡效果,执行完毕后,卸载动画
requestAnimationFrame(() => {
div.classList.remove('enter-from')
div.classList.add('enter-to')
div.addEventListener('transitionend', () => {
div.classList.remove('enter-to')
div.classList.remove('enter-active')
})
})
}
function outerAnimation(div) {
div.classList.add('enter-to')
div.classList.add('enter-active')
// 下一帧,再执行动画的过渡效果,执行完毕后,卸载元素
requestAnimationFrame(() => {
div.classList.remove('enter-to')
div.classList.add('enter-from')
div.addEventListener('transitionend', () => {
document.body.removeChild(div)
})
})
}
</script>
</html>
api说明
interface TransitionProps {
/**
* 用于自动生成过渡 CSS class 名。
* 例如 `name: 'fade'` 将自动扩展为 `.fade-enter`、
* `.fade-enter-active` 等。
*/
name?: string
/**
* 是否应用 CSS 过渡 class。
* 默认:true
*/
css?: boolean
/**
* 指定要等待的过渡事件类型
* 来确定过渡结束的时间。
* 默认情况下会自动检测
* 持续时间较长的类型。
*/
type?: 'transition' | 'animation'
/**
* 显式指定过渡的持续时间。
* 默认情况下是等待过渡效果的根元素的第一个 `transitionend`
* 或`animationend`事件。
*/
duration?: number | { enter: number; leave: number }
/**
* 控制离开/进入过渡的时序。
* 默认情况下是同时的。
*/
mode?: 'in-out' | 'out-in' | 'default'
/**
* 是否对初始渲染使用过渡。
* 默认:false
*/
appear?: boolean
/**
* 用于自定义过渡 class 的 prop。
* 在模板中使用短横线命名,例如:enter-from-class="xxx"
*/
enterFromClass?: string
enterActiveClass?: string
enterToClass?: string
appearFromClass?: string
appearActiveClass?: string
appearToClass?: string
leaveFromClass?: string
leaveActiveClass?: string
leaveToClass?: string
}
测试代码
<Transition>
<div v-if="ok">toggled content</div>
</Transition>