今天学习vue的动画的时候,感觉机制有点繁琐,总结一下。

过渡

Vue里使用动画需要用到一个封装好的组件<transition>Vue官方文档是这么介绍的:

Vue 提供了 <transition>的封装组件,在下列情形中,可以给任何元素和组件添加进入/离开过渡

  • 条件渲染 (使用 v-if)
  • 条件展示 (使用 v-show)
  • 动态组件
  • 组件根节点

原理

原理是这样的:
以一个最简单的情况为例:

<transition>
	<div v-if:"sth">Fighting!</div>
</transition>

当动画在以上四种情况下被触发时,会往<transition>包裹的那个元素(注意<transition>中只能有一个元素)里添加class

  • 当动画被触发的第一刻,fade-enterfade-enter-active会被添加上,显示在最终的DOM Tree里就会是这样:
<div class="fade-enter fade-enter-active">Fighting!</div>
  • 动画执行过程中,fade-enter会被删去,fade-enter-to会被添加上,显示在最终的DOM Tree里就会是这样:
<div class="fade-enter-active fade-enter-to">Fighting!</div>
  • 动画执行结束后,fade-enter-tofade-enter-active会被删去,DOM元素回复成初始的样子,如果这个DOM元素还在的话(v-if=true的话),显示在最终的DOM Tree里就会是这样:
<div>Fighting!</div>

图片来源:慕课网
同样,消失的动画过程也是通过修改类来实现的:
图片来源:慕课网

实现

下面是一个简单的例子:

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .fade-enter,.fade-leave-to {
            opacity: 0;
        }
        .act {
            transition: opacity 10s;
        }
        #container{
            width: 200px;
            height: 100px;
            margin:0 auto;
            border: 5px solid black;
            position: relative;
        }
        #app{
            position: absolute;
            left:0;
            right:0;
            top:0;
            bottom:0;
            margin:auto;
        }
    </style>
    <script src="../vue.js"></script>
</head>

<body>
    <div id="container">
        <div id="app">
            <transition name="fade" enter-active-class="act" leave-active-class="act">
                <div v-if="show">123</div>
            </transition>
            <button @click=handleClick>点击切换</button>

        </div>
    </div>

    <script>
        var vm = new Vue({
            el: '#app',
            data: {
                show: true
            },
            methods: {
                handleClick: function () {
                    this.show = !this.show;
                }
            }
        })

    </script>
</body>

下面这块代码有几个需要注意的地方:

            <transition name="fade" enter-active-class="act" leave-active-class="act">
                <div v-if="show">123</div>
            </transition>
  1. transition的name属性是自定义的,可以不写,如果不写name属性,那么.fade-enter,.fade-leave-to,.fade-enter-active等都会取默认值.v-fade-enter.v-leave-to,.v-enter-active
  2. enter-active-class="act" leave-active-class="act"的意思是,我们可以自定义类的名称,这里我把fade-enter-activefade-leave-active手动指向了act,所以可以看到我在style标签里写了:
        .act {
            transition: opacity 10s;
        }

@keyframes动画

@keyframes是CSS3的一个新特性,可以按照帧来定义一些简单的动画,下面是一个简单的缩放的例子:

        @keyframes bounce-in {
            0% {
                transform: scale(0);
            }

            50% {
                transform: scale(1.5);
            }

            100% {
                transform: scale(1);
            }
        }

然后我们只需要将enter-active-classleave-active-class指向的类指定为我们自己编写的类即可:

<div id="app">
	<transition enter-active-class="enter" leave-active-class="leave">
		<div v-if = "show"> Hello World! </div>
	</transition>
</div>
	var vm = new Vue({
	    el: "#app",
	    data: {
	        show: true
	    },
	    methods: {
	        handleClick() {
	            this.show = !this.show;
	        }
	    }
	})

然后,在我们自己写的类里设置动画

        .enter {
            transform-origin: left center;  /* 缩放的起点是左边中间*/
            animation: bounce-in 1s;
        }

        .leave {
            transform-origin: left center;
            animation: bounce-in 2s;
        }

使用animated.css

animated.css是封装好的一些基于@keyframes的一些动画,使用起来十分简单:

  • 首先要引入animated.css,这里直接用CDN的形式引入压缩后的animate.min.css
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
  • 直接在元素的类名上加上基础的animate__animated,然后再加上想要实现的动画即可,比如"animate__swing"。(注意这里下划线是两个)。

具体到vue里,只需要在<transition>的属性中把enter-active-classleave-active-class指向成animate__animated以及我们想要的动画即可,比如"animate__swing"

比如我把进入设置为摇晃进场的效果,把离开效果设为X轴摇晃(也就是左右摇晃)离场的效果。

注意,这里还设置了一个appear-active-class(表示appear的动画效果)和一个空的属性appear(表示启用appear),意思是在该元素第一次渲染的时候设置它的动画效果。(注意第一次渲染进场是两个被区分的概念,进场是这个元素离场之后又重新出现在页面上)

    <div id="app">
        <transition 
            name = "fade" 
            enter-active-class="animate__animated animate__swing" 
            leave-active-class="animate__animated animate__shakeX"
            appear
            appear-active-class = "animate__animated animate__swing"
        >
            <div v-show="show">Hello World</div>
        </transition>
            <button @click="handleClick">点击切换</button>
    </div>

同时使用过渡和@keyframes动画

在使用了animated.css的基础上,只要把过渡效果叠加上去即可。

要叠加的过渡效果:

        .fade-enter,.fade-leave-to{
            opacity: 0;
        }
        .fade-enter-active,.fade-leave-active{
            transition: opacity 3s;
        }

把要叠加的效果加入到enter-active-classleave-active-class里。

    <div id="app">
        <transition 
            name = "fade" 
            enter-active-class="animate__animated animate__swing fade-enter-active" 
            leave-active-class="animate__animated animate__shakeX fade-leave-active"
            appear
            appear-active-class = "animate__animated animate__swing"
        >
            <div v-show="show">Hello World</div>
        </transition>
            <button @click="handleClick">点击切换</button>
    </div>

动画时长的问题

我们注意到,transition的时长我们设为3s,而animated有自己设置的动画时间,一般是1s,要么vue要以哪一个为准呢?这需要我们自己来设置。
通过在<transition>里添加type这个属性,我们可以设置以哪个效果时长为准。type="transition"就是以transition过渡动画的时长为准。

        <transition 
            type="transition"
            name="fade" 
            enter-active-class="animate__animated animate__swing fade-enter-active" 
            leave-active-class="animate__animated animate__shakeX fade-leave-active"
            appear
            appear-active-class = "animate__animated animate__swing"
        >

当然这个时间还可以我们自己用:duration来设置:

        <transition 
            :duration = "{enter:5000,leave:10000}"
            name="fade" 
            enter-active-class="animate__animated animate__swing fade-enter-active" 
            leave-active-class="animate__animated animate__shakeX fade-leave-active"
            appear
            appear-active-class = "animate__animated animate__swing"
        >
Logo

前往低代码交流专区

更多推荐