[动画] vue3过渡和动画并用小技巧
构建一个过渡和动画并用的代码
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo</title>
<style>
@keyframes comein {
0% {
transform: translateX(-120px)
}
100% {
transform: translateX(0px)
}
}
@keyframes comeout {
0% {
transform: translateX(0px)
}
100% {
transform: translateX(-120px)
}
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
.v-enter-to,
.v-leave-from {
opacity: 1;
}
.v-enter-active {
animation: comein 3s;
transition: opacity 3s ease-out;
}
.v-leave-active {
animation: comeout 3s;
transition: opacity 3s ease-out;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
isShow: false
}
},
methods: {
hanldClick() {
this.isShow = !this.isShow
}
},
template: `
<transition>
<div v-if="isShow">willem</div>
</transition>
<button @click="hanldClick">切换动画</button>
`
})
const vm = app.mount("#app")
</script>
为了查看方便,把过渡和动画的时间都变成3秒。然后到浏览器中进行查看,可以看到这时候过渡和动画都非常正常。
过渡和动画时长不一致的处理
有些时候过渡和动画时长并不是一致的,比如过渡时间是7秒,动画时间还是3秒。
在进场动画时,你可能还感觉不到Bug,但在出场动画时,就会有严重的问题。
动画结束后,为了显示过渡效果,元素又回到了页面上,直到过渡结束,才消失。
为了解决这个问题,可以在 <transition>
标签上加入 type='animation'
属性,意思是不管过渡时长是多少,动画结束,整个过程结束。
template: `
<transition type="animation">
<div v-if="isShow">willem</div>
</transition>
<button @click="hanldClick">切换动画</button>
`
当然你也可以把动画时间调长为7秒,然后过渡调整为3秒,这时候你可以使用type='transition'
,属性,避免Bug。
现在的意思就是以过渡时长为准,过渡结束,动画结束。我们来看一下效果。
.v-enter-active {
animation: comein 7s;
transition: opacity 3s ease-out;
}
.v-leave-active {
animation: comeout 7s;
transition: opacity 3s ease-out;
}
模板部分修改如下:
template: `
<transition type="transition">
<div v-if="isShow">willem</div>
</transition>
<button @click="hanldClick">切换动画</button>
`
这时候过渡结束,动画也随之结束。不过这时候看起来很不自然,因为子还没有走到它应该走的位置,结果动画结束了,就会有跳帧现象。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo</title>
<style>
@keyframes comein {
0% {
transform: translateX(-120px)
}
100% {
transform: translateX(0px)
}
}
@keyframes comeout {
0% {
transform: translateX(0px)
}
100% {
transform: translateX(-120px)
}
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
.v-enter-to,
.v-leave-from {
opacity: 1;
}
.v-enter-active {
animation: comein 7s;
transition: opacity 3s ease-out;
}
.v-leave-active {
animation: comeout 7s;
transition: opacity 3s ease-out;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
isShow: false
}
},
methods: {
hanldClick() {
this.isShow = !this.isShow
}
},
template: `
<transition type="transition">
<div v-if="isShow">willem</div>
</transition>
<button @click="hanldClick">切换动画</button>
`
})
const vm = app.mount("#app")
</script>
属性控制动画和过渡时长
还有一种情况,就是我们不管CSS中的动画和过渡时长,以标签为准。可以绑定属性<transition :duration="1000">
来控制时长,意思是1
秒后,结束动画和过渡。
注意这里的1000
是毫秒的意思,也就是1
秒。
template: `
<transition :duration="1000">
<div v-if="isShow">willem</div>
</transition>
<button @click="hanldClick">切换动画</button>
`
这时候再到浏览器中查看,可以看到 1
秒种过渡和动画虽没有完成,但是还是停止了。
duration
除了能写一个数字之外,还可以写对象进去,比如入场的时候 1
秒种,出厂的时候 3
秒钟,就可以这样写。
<transition :duration="{enter:1000,leave:3000}">
这就是动画和过渡同时使用时的一些控制选项和注意事项。
下节我们学习一下用JavaScript配合Vue3来制作动画。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo</title>
<style>
@keyframes comein {
0% {
transform: translateX(-120px)
}
100% {
transform: translateX(0px)
}
}
@keyframes comeout {
0% {
transform: translateX(0px)
}
100% {
transform: translateX(-120px)
}
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
.v-enter-to,
.v-leave-from {
opacity: 1;
}
.v-enter-active {
animation: comein 7s;
transition: opacity 3s ease-out;
}
.v-leave-active {
animation: comeout 7s;
transition: opacity 3s ease-out;
}
</style>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.0.2/vue.global.js"></script>
</head>
<body>
<div id="app"></div>
</body>
<script>
const app = Vue.createApp({
data() {
return {
isShow: false
}
},
methods: {
hanldClick() {
this.isShow = !this.isShow
}
},
template: `
<transition :duration="{enter:1000,leave:3000}">
<div v-if="isShow">willem</div>
</transition>
<button @click="hanldClick">切换动画</button>
`
})
const vm = app.mount("#app")
</script>
</html>