Vue中的动画特效

1.CSS动画原理

动画进入:  动画如果不给名字,默认:v-enter

原理:在某一时刻给 div 添加 或 删除一些样式

<style>
    .fade-enter{
        opacity:0;
    }
    .fade-enter-active{
        transition: opacity 1s; //对opacity有一个监控,如果有变化则让opacity在3s中从0变到一个opacity的值。
    }
}
</style>
<div id='root'>
    <transition name='fade'>  <!--如果不给name,动画默认名字v-enter -->
        <div v-show='show'>hello world</div>
    </transition>
</div>
<!--
动画原理说明:当动画开没执行的一瞬间,vue会帮我们在div标签上加fade-enter 和 fade-enter-active 样式,
fade-enter-active的执行周期:动画还没开始,准备开始执行第一帧时就存在了,到动画结束时才被移除
当执行到第二帧的时候,fade-enter 被删除,同时 fade-enter-active 中的opacity 检测到变化,就在1s 中变化opacity的值
-->
View Code

 

动画离开:

 

<style>
    .fade-leave-to{
        opacity:0;
    }
    .fade-leave-active{
        transition: opacity 3s; 
    }
}
</style>
<div id='root'>
    <transition name='fade'>
        <div v-show='show'>hello world</div>
    </transition>
</div>
<!--
动画原理说明:动画开始和结束的瞬间,页面上都有一个fade-leave-active,在动画的运行过程中,要求时刻监听着 div 的opacity这个属性,一旦发生变化,就让他 三秒钟 进行慢慢的过渡。
第一帧的时候,动画把持原有的状态,当进入第二帧时,div 多了一个 fade-leave-to 的属性,fade-leave-active 检测到 opacity 有变化,则在3秒钟 对opacity 进行过渡
-->
View Code

案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue.js"></script>
    <style>
        .v-enter,
        .v-leave-to {
            opacity: 0;
        }
        .v-enter-active,
        .v-leave-active {
            transition: all 2s;
        }
    </style>
</head>
<body>
    <div class="app">
        <transition>
            <div v-if='show'>一个有CSS特效的内容</div>
        </transition>
        <button @click='btnClick'>切换</button>
    </div>
    <script>
        new Vue({
            el: '.app',
            data: {
                show: true
            },
            methods: {
                btnClick: function() {
                    this.show = !this.show;
                }
            }
        });
    </script>
</body>
</html>
View Code

2.vue中使用animate.css库

第一步:先在页面中引入animate.css库

第二步:必须自定义动画样式名字(animated)

<!--<transition enter-active-class='animated 动画名称'>-->
<transition enter-active-class='animated swing'  leave-active-class='animated shake'>

3.使用 appear 让元素第一次显示的时候也有动画(初次动画)

<transition
    appear   <!--声明-->
    enter-active-class='animated swing'
    leave-active-class='animated shake'
    appear-active-class='animated swing'  <!--设置第一次显示的时候的动画-->
>
    <div v-show='show'>带有动画效果的文字</div>
</transition>

4.同时使用过渡和动画

<transition
    <!-- type:'transition' --><!--定义以自己写的动画时长为准-->
    :duration:"{enter:5000,leave:10000}"<!--分别定义动画开始时间用5s,离开时间用10s-->
    appear   <!--声明-->
    enter-active-class='animated swing  v-enter-active' <!--同时使用过渡和动画-->
    leave-active-class='animated shake  v-leave-active'<!--同时使用过渡和动画-->
    appear-active-class='animated swing'  <!--设置第一次显示的时候的动画-->
>
<!--如果过渡和自己定义的动画时长不一致,特意定义使用谁的时长为准(type:'transition')-->

5.vue中的 JS 动画与 velocity.js

1)vue中也有很多JS动画钩子

<transition 
    name='fade'
    @before-enter='beforeEnter'  <!--元素即将显示时,事件被触发时-->
    @enter='enterClick'   <!--执行动画时,事件被触发-->
    @after-enter='afterEnter' <!--动画完成时,事件被触发-->
>
    <div v-show='show'>文字内容</div>
</transition>
methods:{
    beforeEnter:function(el){ // before-enter 有一个参数 el 是div元素
        el.style.color='red';
    },
    enterClick:function(el,done){  //enter 有两个参数,done是回调函数
        setTimeout(function(){
            el.style.color='green'
        },2000);
        setTimeout(function(){
            done();  //调用回调函数,才会执行 after 钩子
        },4000);
    },
    afterEnter:function(el){    //after里面有一个参数
        el.style.color="#000";
     }
}

2)velocity.js

通过 velocity.js 的简单语法可以实现酷炫的动画效果

methods:{
    beforeEnter:function(el){ // 设置opacity=0
        el.style.opacity=0;
    },
    enterClick:function(el,done){  
        Velocity(el,{ //元素名
            opacity:1  //设置效果
        },{
            duration:1000,  //设置过渡时间
            complete:done  // 回调函数,执行after
        });
    },
    afterEnter:function(el){    //
        console.log('动画结束');
     }
}

 6.多个元素或组件过渡

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue.js"></script>
    <style>
        .v-enter {
            opacity: 0;
        }   
        .v-enter-active {
            transition: all 1s;
        }
    </style>
</head>
<body>
    <div class="root">
        <!-- mode过渡方式 out-in:先隐藏再显示 in-out:先显示再隐藏 -->
        <transition mode='out-in'> 
            <!-- 
            <child v-if='show'>child</child>
            <child-one v-else>child-one</child-one>
            -->
            <!-- 动态组件过渡 -->
            <component :is='type'></component>
        </transition>

        <button @click='btnClick'>切换</button>
    </div>
    <script>
        Vue.component('child', {
            template: "<div>child-组件</div>"
        });
        Vue.component('child-one', {
            template: '<div>child-one-组件</div>'
        });
        var vm = new Vue({
            el: '.root',
            data: {
                // show: 'true'
                type: 'child'
            },
            methods: {
                btnClick: function() {
                    // this.show = !this.show;
                    this.type = (this.type == 'child' ? 'child-one' : 'child');
                }
            }
        });
    </script>
</body>
</html>

7.Vue中的列表过渡(transition-group)

用法和 transition 一致

<transition-group>
    <div v-for='item of list' :key='item.id'>{{item.title}}</div>
</transition-group>

<!--等同于多组加了动画的div-->
<transition>
    <div>Hello World</div>
</transition>
<transition>
    <div>Hello World</div>
</transition>
    ...

案例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./js/vue.js"></script>
    <style>
        .v-enter,
        .v-leave-to {
            opacity: 0;
        }     
        .v-enter-active,
        .v-leave-active {
            transition: all 1s;
        }
    </style>
</head>
<body>
    <div class="app">
        <button @click='btnAdd'>Add</button>
        <!--动画组-->
        <transition-group> 
            <!--for循环中  这里的key值不建议使用index,会影响性能-->
            <div v-for='item of list' :key='item.id'>{{item.title}}</div>
        </transition-group>
    </div>
    <script>
        var count = 0;
        var vm = new Vue({
            el: '.app',
            data: {
                list: []
            },
            methods: {
                btnAdd: function() {
                    this.list.push({
                        id: count++,
                        title: 'Hello World' + count
                    });
                }
            }
        });
    </script>
</body>
</html>
View Code

 

posted @ 2020-04-19 23:43  晴天宝宝i  阅读(2995)  评论(0编辑  收藏  举报