43. [动画]JS+Vue3制作动画和钩子函数
有时候我们不使用 CSS 制作动画,而使用 JS 来制作动画。虽然 CSS 的动画比 JS 的效率要高,但 JS 在操作 DOM 和时间控制上有着优势。所以这节我们就来学习一下如何使用 JavaScript+Vue3 来制作动画。
指定不使用 CSS 动画
新建一个文件Demo43.html
,代码如下。
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mybj</title> <style> @keyframes comein{ 0%{ transform :translateX(-120px) } 100%{ transform :translateX(0px) } } @keyframes comeout{ 0%{ transform :translateX(0px) } 100%{ transform :translateX(-120px) } } .v-enter-active{ animation: comein 1s; } .v-leave-active{ animation: comeout 1s; } </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">码云笔记前端博客</div> </transition> <button @click="hanldClick">切换动画</button> ` }) const vm = app.mount("#app") </script>
如果不使用 CSS 动画,需要在<transition>
标签上加入:css="false"
。
<transition :css="false">
加上这个绑定属性的意思就是,我不再使用 CSS 作为动画了。可以到浏览器中看一下,此时的动画效果已经不在起作用。
此时 CSS 的动画没有用处了,你可以进行删除。
使用 JS 编写动画效果
Vue 为了能让我们使用 JS 动画效果,为我们提供了一些钩子函数。所谓钩子函数 ,就是在某一时刻会被自动调用的函数(类似之前我们讲的生命周期函数)。
before-enter 钩子函数
先来看第一个钩子函数before-enter
,在动画开始前执行的函数。我们给这个钩子,绑定一个方法,比如这个方法叫做handleBeforeEnter
。
<transition :css="false" @before-enter="handleBeforeEnter" > <div v-if="isShow">码云笔记前端博客</div> </transition>
写好钩子函数后,再编写对应的方法handleBeforeEnter
。
handleBeforeEnter(element){ element.style.color="red" },
注意,这个方法接收一个参数element
,这个参数就是动画的 DOM 元素,有了它你就可以操作动画了。现在程序的意思是在动画开始前,把字体颜色变为红色。
enter 钩子函数
当动画进入时,可以使用钩子函数enter
。这里我们作一个如果字体是红色,就变成绿色;如果是绿色就变成红色的效果,并且是半秒钟变化一次。
在 template 的<transition>
标签里加入enter
钩子函数。
<transition :css="false" @before-enter="handleBeforeEnter" @enter="handleEnterActive" >
编写钩子函数的业务逻辑。
handleEnterActive(element,done){ setInterval(()=>{ const color=element.style.color; if(color=='red'){ element.style.color ="green" }else{ element.style.color="red" } },500) }
但现在如何让这个动画停下来那?其实这个还是比较麻烦的。需要先为setInterval
指定一个变量animation
,然后使用setTimeout
在 1500 毫秒后停止这个动画。
handleEnterActive(element,done){ const animation=setInterval(()=>{ const color=element.style.color; if(color=='red'){ element.style.color ="green" }else{ element.style.color="red" } },500) setTimeout(()=>{ clearInterval(animation) },1500) }
此时在到浏览器中进行预览就可以看到,动画停止了。那我们再来说说done
参数的作用,其实done
相当于得知动画执行结束后通知执行下一个钩子函数after-enter
,如果不通知无法进入下一个钩子函数。
after-enter 钩子函数
这个钩子函数是当动画结束时执行的。比如我们想在动画结束后弹出一个alter
对象,就可以先写一个after-enter
钩子函数,然后利用enter
钩子中的done
进行通知它动画执行结束。
<transition :css="false" @before-enter="handleBeforeEnter" @enter="handleEnterActive" @after-enter="handleEnterEnd" >
然后在handleEnterActive
的clearInterval
后面使用done()
进行通知。
setTimeout(()=>{ clearInterval(animation) done() },1500)
这时候才会执行handleEnterEnd
里边的方法,弹出对话框。
handleEnterEnd(){ alert('mybj123.com') }
这里我们只学了入场动画的钩子函数,当然还有三个出场动画的钩子函数。
before-leave
:离场动画执行之前leave
:开始执行离场动画leave-after
: 离场动画执行结束
离场动画我们就不讲了,你可以自己试一下就可以了。
为了方便大家学习,附上本节代码:
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mybj</title> <style> @keyframes comein{ 0%{ transform :translateX(-120px) } 100%{ transform :translateX(0px) } } @keyframes comeout{ 0%{ transform :translateX(0px) } 100%{ transform :translateX(-120px) } } .v-enter-active{ animation: comein 1s; } .v-leave-active{ animation: comeout 1s; } </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 }, handleBeforeEnter(element){ element.style.color="red" }, handleEnterActive(element,done){ const animation=setInterval(()=>{ const color=element.style.color; if(color=='red'){ element.style.color ="green" }else{ element.style.color="red" } },500) setTimeout(()=>{ clearInterval(animation) done() },1500) }, handleEnterEnd(){ alert('mybj123.com') } }, template: ` <transition :css="false" @before-enter="handleBeforeEnter" @enter="handleEnterActive" @after-enter="handleEnterEnd" > <div v-if="isShow">码云笔记前端博客</div> </transition> <button @click="hanldClick">切换动画</button> ` }) const vm = app.mount("#app") </script>
码云笔记 » 43. [动画]JS+Vue3制作动画和钩子函数