Vue-过渡&动画

1. Vue中的CSS动画原理

如果要元素具有动画效果,则需要在元素外部包裹一个transition(过渡)标签,这样Vie就会自动帮我们构建一个动画流程;同时我们可以给标签通过name属性取一个名字,(如果不取名,Vue默认的class前缀是v)例如:

    <div id="root">
        <transition name="fade">
            <div v-if="show">Hellodiv>
        transition>
        <button @click="handleClick">clickbutton>
    div>

(1)显示过渡效果的流程:
Vue-过渡&动画_第1张图片

  • 在动画即将被执行的一瞬间,它会往div元素里边增加两个class——fade-enter和fade-enter-active;
  • 当动画第一帧执行完毕,即将开始第二帧动画的时候,Vue会帮助我们干两件事情——去掉fade-enter这个class,同时增加fade-enter-to这个新的class;
  • 动画会继续执行,直到要结束的时候,把之前增加的两个class——fade-enter-active和fade-enter-to删除掉

(2)隐藏过渡效果的流程:
Vue-过渡&动画_第2张图片
跟显示的流程类似,这里我就不赘述了嘻嘻

实际上Vue实现动画是通过——在某一时刻,自动地往一些标签上增加一些样式来实现的

kangkang示例代码:


<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS动画原理title>
    <script src="JS/vue.js">script>
    <style>
        .fade-enter,.fade-leave-to {
            opacity: 0;
        }
        .fade-enter-active, .fade-leave-active{
            transition: opacity 3s;
        }
    style>
head>
<body>
    <div id="root">
        <transition name="fade">
            <div v-if="show">hellodiv>
        transition>
        <button @click="handleClick">clickbutton>
    div>
    <script>
        var vm = new Vue({
            el:"#root",
            data:{
                show:true
            },
            methods: {
                handleClick(){
                    this.show=!this.show
                }
            },

        })
    script>
body>
html>

2.animate.css的使用

有时候为了实现一些复杂的动画效果,要写很多代码,看得头晕目眩;怎怎么样不用写那么多代码,又能实现酷炫的动画效果呢?

animate.css库来帮你!它和我们自己使用css的keyframe效果是一样的,只是封装好了方面我们使用(搬砖)。。那怎么用css库呢?
(1)首先,animate官网下载animate.css文件到代码文件中;
(2) 然后,html页面通过link标签引入animate.css;
(3)最后,使用动画库animate.css需要注意:

  1. 需要使用自定义class名字的形式
  2. class类里需要包含animated类
  3. 根据入场出场的不同方式,使用不同动画效果
        <transition name="fade"
                    enter-active-class="animated shake"
                    leave-active-class="animated swing">
            <div v-if="show">hellodiv>
        transition>

3.同时使用过渡(transition)和动画(animate)

为了让页面第一次加载的时候就出现animate.css的@keyframe动画效果:

  • 需要在transition标签内声明appear并且指定其动画效果
  • 同时使用过渡(transition)和动画,则需要新增fade-enter等样式
  • 若两种动画效果时长不同,可通过type指定其中一个为标准时长,例如:type="transition"
  • 或者通过:duration自定义一个动画时长

我们可以通过控制台查看动画样式的增加与销毁,确定动画执行的时间
kangkang示例代码:

<link rel="stylesheet" href="CSS/animate.css">
    <style>
        .fade-enter,.fade-leave-to{
            opacity: 0;
        }
        .fade-enter-active,.fade-leave-active{
            transition: opacity 3s;
        }
    style>
head>
<div id="root">
    <transition name="fade"
                :duration="{enter:5000,leave:10000}"
                appear
                appear-active-class="animated swing"
                enter-active-class="animated shake fade-enter-active"
                leave-active-class="animated swing fade-leave-active">
        <div v-if="show">hellodiv>
    transition>

    <button @click="handleClick">clickbutton>
div>
<script>
    var vm = new Vue({
        el:"#root",
        data:{
            show:true
        },
        methods: {
            handleClick(){
                this.show=!this.show
            }
        },

    })
script>

4.JS动画和Velocity.js结合使用

(1)JS动画

我们以前实现动画都是通过css来实现,那有没有办法通过js来实现呢?
答案是:有有有!!!

Vue之中提供了很多js动画的钩子,那怎么去用呢?

transition标签里边,除了写一个name的属性,还可以去绑定一个before-enter事件,当事件被触发的时候,我们让它执行一个自定义函数:
Vue-过渡&动画_第3张图片
其实before-enter这个函数,会接收到一个el参数,这个el就是动画包裹的div标签,那我们就可以通过el来改变div的样式,比如el.style.color='red'

我们还可以再绑定一个enter事件,它发生在before-enter这个函数被触发结束之后,是运行的真正的动画效果,会接收两个参数——el,和done(回调函数),在写函数的时候,我们需要设置一个延时器setTimeout:

handleEnter(el,done){
                setTimeout(() => {
                    el.style.color='green'
                    done()
                }, 2000);
            },
//这个enter函数里的done非常重要
//动画执行结束之后,我们需要手动地调用done这个回调函数
//相当于我们告诉Vue:这个动画函数已经执行完了

当done()这个回调函数被调用了之后,Vue又会触发一个after-enter事件,它执行的函数同样需要接收一个el参数,以便我们通过它修改样式

我们上边讲的before-enter、enter、after-enter动画都是js的入场动画,那有入场就会有出场动画,它对应的钩子函数(或者说事件名字),分别是before-leave、leave、after-leave,用法都一样,就不啰嗦了,挥~

讲完了js动画,我们来认识一个大朋友

(2)JS常用的动画库valocity.js

使用方法跟animate差不多——先在valocity官网下载,然后页面通过script标签引入valocity.js文件,最后在函数那里使用就好了。

  • 调用Velocity()函数
  • 传递参数——el,{对象里边写上想实现的动画效果的css代码},{动画执行的时长}
  • 执行动画时长后边还需要跟一个complete的配置参数,意思是velocity函数执行完这个动画了之后,done()这个回调函数会自动执行,告诉Vue:我这part的动画执行完成了,可以进行下一步了。
Velocity(el,{opacity:1},{duration:2000,complete:done})

5.多个元素/组件的过渡动画

(1)多个元素的过渡

Vue为了高效的渲染,所以元素进行切换的时候,会尽可能地去复用dom,这就导致了,我们添加的过渡效果不会生效。
Vue-过渡&动画_第4张图片
像这样有相同标签名的元素切换时,需要通过key设置唯一的值来标记,好以让 Vue 能够区分它们:
在这里插入图片描述
同时,还可以通过mode指定元素的显示隐藏顺序:

<transition name="fade" mode="in-out">
 <!-- in-out表示:要显示的元素会先进入,要隐藏的元素才会随之隐藏 -->

(2)多个组件的过渡

这里会用到我们小学二年级学过的动态组件

  1. 首先,我们要定义两个子组件
  2. 然后,父组件通过compon标签和is属性绑定组件名调用子组件
    <style>
        .fade-enter,.fade-leave-to{
            opacity: 0;
        }
        .fade-enter-active,.fade-leave-active{
            transition: opacity 2s;
        }
    style>
head>
<body>
    <div id="root">
        <transition name="fade">
            <component :is="type">component>
        transition>
        <button @click="handleClick">clickbutton>
    div>
    <script>
        Vue.component('child01',{
            template:'
I am child01
'
}) Vue.component('child02',{ template:'
I am child02
'
}) var vm = new Vue({ el:"#root", data:{ // show:true type:'child01' }, methods: { handleClick(){ // this.show=!this.show this.type = this.type === 'child01' ? 'child02' : 'child01' } }, })
script>

这样写,和下面用v-if条件渲染子组件的效果是一样一样滴

<transition>
	<child v-if="show">child>
	<child-one v-else>child-one>
transition>

6.列表过渡

以前呢,我们做动画的效果,都是对单个元素进行显示和隐藏,或者对两个元素之间进行来回的切换显示。

那现在,如果我们想对一个列表增加动画效果,比如——点击按钮,增加/删除某一项,实现列表的过渡效果,该肿么办捏( ̄▽ ̄)*

transition-group闪亮登场!!!

(1)在元素的最外层,包裹一个transition-group标签
(2)在style里自定义动画的css样式,transition-group标签没有name的话,默认使用v前缀

当我们在元素外层包裹transition-group的时候,相当于给列表中的每一项都包裹了transition,而每一个单个元素的过渡,Vue都会在元素显示/隐藏的时候,动态地找到时间点,增加一些对应的class(这些class是我们原先自定义好的),这样就能实现列表的过渡动画了。

7.动画的封装(可复用)

有时候,同一个动画效果可能在多个地方都会用到,那我们就需要对动画进行封装,让它变得可复用,方便开发。

那怎么封装呢?

(1)建一个组件
(2)把transition或者transition-group标签放在组件的模板里边
(3)transition标签里放一个slot标签(也就是让外部传一些dom元素)
(4)再通过v-if判断外部传来的dom是否要显示
(5)在使用动画的时候,不用像之前一样给元素包裹transition标签,只需要写这个动画的组件名就可以了
(6)使用js动画——在模板里边绑定一个js钩子函数,并自定义动画函数
(7)使用组件时,需要传插槽里的内容,还有用来条件渲染的show的变量

<div id="root">
    <fade :show="show">
        <div>hellodiv>
    fade>
    <button @click="handleClick">clickbutton>
div>
<script>
    Vue.component('fade',{
        props:['show'],
        template:'',
        methods:{
            handleBeforeEnter(el){
                el.style.color='red'
            },
            handleEnter(el,done){
                setTimeout(() => {
                    el.style.color='green'
                    done()
                }, 2000);
            },
            handleAfterEnter(el){
                // el.style.color='white'
                console.log('end')
            }
        }
    })
    var vm = new Vue({
        el:"#root",
        data:{
            show:true
        },
        methods: {
            handleClick(){
                this.show=!this.show
            }
        },

    })
script>

这样一来,所有的动画都写在组件里,外部简单地调用即可,也无需在外部的style里写css样式,就很好地实现了动画的封装,妙哉~

你可能感兴趣的:(Vue)