43 JS+Vue3制作动画和钩子函数

Posted wgchen~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了43 JS+Vue3制作动画和钩子函数相关的知识,希望对你有一定的参考价值。

阐述

有时候我们不使用CSS制作动画,而使用JS来制作动画。

虽然CSS的动画比JS的效率要高,但JS在操作DOM和时间控制上有着优势。所以这节我们就来学习一下如何使用javascript+Vue3来制作动画。

指定不使用CSS动画

<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-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">willem</div>
        </transition>
        <button @click="hanldClick">切换动画</button>

        `
    )
    const vm = app.mount("#app")
</script>
</html>

如果不使用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">willem</div>
</transition>

写好钩子函数后,再编写对应的方法 handleBeforeEnter

注意,这个方法接收一个参数 element,这个参数就是动画的DOM元素,有了它你就可以操作动画了。

现在程序的意思是在动画开始前,把字体颜色变为红色。

<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-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"
            ,
        ,
        template: `  
        <transition :css="false" @before-enter="handleBeforeEnter">
            <div v-if="isShow">willem</div>
        </transition>
        <button @click="hanldClick">切换动画</button>

        `
    )
    const vm = app.mount("#app")
</script>
</html>

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,然后使用setTimeout1500毫秒后停止这个动画。

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,如果不通知无法进入下一个钩子函数。

<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-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
            ,
            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)
            
        ,
        template: `  
        <transition 
            :css="false" 
            @before-enter="handleBeforeEnter"
            @enter="handleEnterActive"
        >
            <div v-if="isShow">willem</div>
        </transition>
        <button @click="hanldClick">切换动画</button>

        `
    )
    const vm = app.mount("#app")
</script>
</html>

after-enter 钩子函数

这个钩子函数是当动画结束时执行的。
比如我们想在动画结束后弹出一个alter对象,就可以先写一个after-enter钩子函数,然后利用enter钩子中的done进行通知它动画执行结束。

<transition 
    :css="false" 
    @before-enter="handleBeforeEnter"
    @enter="handleEnterActive"
    @after-enter="handleEnterEnd"
>

然后在 handleEnterActiveclearInterval 后面使用 done()进行通知。

setTimeout(()=>
    clearInterval(animation)
    done()
,1500)

这时候才会执行 handleEnterEnd 里边的方法,弹出对话框。

handleEnterEnd()
    alert('willem.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>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-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
            ,
            handleEnterEnd()
                alert('willem.com')
            ,
            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)

                setTimeout(()=>
                    clearInterval(animation)
                    done()
                ,1500)
            
        ,
        template: `  
        <transition 
            :css="false" 
            @before-enter="handleBeforeEnter"
            @enter="handleEnterActive"
            @after-enter="handleEnterEnd"
        >
            <div v-if="isShow">willem</div>
        </transition>
        <button @click="hanldClick">切换动画</button>

        `
    )
    const vm = app.mount("#app")
</script>
</html>

以上是关于43 JS+Vue3制作动画和钩子函数的主要内容,如果未能解决你的问题,请参考以下文章

vue3学习随便记12

vue3学习随便记12

vue3学习随便记13

vue3学习随便记13

Vue3 生命周期钩子函数

Vue2与Vue3的区别