• Vue中的动画效果


    Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
    包括以下工具:

    1. 在 CSS 过渡和动画中自动应用 class
    2. 可以配合使用第三方 CSS 动画库,如 Animate.css
    3. 在过渡钩子函数中使用 JavaScript 直接操作 DOM
    4. 可以配合使用第三方 JavaScript 动画库,如 Velocity.js

    下面分别从这个4个工具来学习Vue动画效果。

    一、单元素/组件的过渡

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

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

    一个典型的例子:

    Html文件

    <div id="app">
            <transition name="fade">
                <div v-if="show">
                    Hello world.
                </div>
            </transition>
            <button @click="handleClick">切换</button>
        </div>
    

      

    js文件

    <script>
    
            // 1. 创建Vue的实例
            let vm = new Vue({
                el:'#app',
                data:{
                    show:false
                },
                methods:{
                    handleClick:function(){
                        this.show = !this.show
                    }
                }
            });
        </script>
    

      

    css文件

    <style>
            .fade-enter-active, .fade-leave-active {
              transition: opacity 2s;
            }
            .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
              opacity: 0;
            }
    </style>
    

      

    这个例子的效果为:点击切换,文字会淡入淡出。

    实现原理:

    1、通过使用transition组件后, Vue 将会做以下处理:

    • 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名。
    • 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。
    • 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)

    2、动画进入时,Vue会添加CSS类,如果没有使用name="fade"的话,类名为v-fade-enter、v-fade-eneter-active等。

    第一帧动画,会自动添加fade-enter和fade-enter-active类

    第二帧动画,会去掉fade-enter类,添加fade-enter-to类

    第三帧动画,会去掉所有enter类

     

     3、动画在离开时同样会添加或删除CSS类

    二、Vue使用animate.css动画库

    1、使用自定义类

    效果为:进入或离开都会有拉升效果。

    注意:这里我们使用了

    name="bounce"替换了默认的fade。当然,如果没有fade的话,也会有v-作为默认开头。
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            
            @keyframes bounce-in {
              0% {
                transform: scale(0);
              }
              50% {
                transform: scale(1.5);
              }
              100% {
                transform: scale(1);
              }
            }
    
    
            .bounce-enter-active {
              animation: bounce-in .5s;
            }
            .bounce-leave-active {
              animation: bounce-in .5s reverse;
            }
    </style>
    
    </head>
    <body>
        <div id="app">
            <transition name="bounce">
                <div v-if="show">
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus.
                </div>
            </transition>
            <button @click="handleClick">切换</button>
        </div>
    
        <script src="js/vue.js"></script>
        <script>
    
            // 1. 创建Vue的实例
            let vm = new Vue({
                el:'#app',
                data:{
                    show:false
                },
                methods:{
                    handleClick:function(){
                        this.show = !this.show
                    }
                }
            });
        </script>
        </body>
        </html>
    

      我们这里还可以使用自定义类:

     

     既然我们可以使用自定义class,那么我们就可以使用开源的第三方CSS库,比如animate.css库。

    https://daneden.github.io/animate.css/

    使用很简单,直接替换上面我们自定义的class就行。

    使用animate.css注意事项:

    1、必须使用自定义class的模式

    enter-active-class=""

    2、animated类放在前面,且是必须的

     

    三、Vue中同时使用过渡和动画

    1、初次动画效果

    上面例子中,我们初次进入的时候没有动画效果,我们可以做如下修改:

     2、如果我们希望在上面的例子中还加入一开始我们说的过渡效果,那该怎么做呢?

     1、因为animate.css有一个自己的动画效果时长,fade也有一个opacity,那么以哪一个为准呢?我们可以使用type="transition"来确定哪个为准。

    2、我们也可以自己设定动画效果时长样式:duration里面的enter为进入时长,leave为动画离开时长,都是针对过渡效果的。

    四、Vue中的js动画配合使用第三方动画库(Velocity.js) 

     Html

    <div id="app">
            <transition name="fade"
            @before-enter="beforeEnter"
            @enter="enter"
            >
                <div v-if="show">
                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus.
                </div>
            </transition>
            <button @click="handleClick">切换</button>
        </div>
    

      

    Js

     methods:{
                    handleClick:function(){
                        this.show = !this.show
                    },
                    beforeEnter: function (el) {
                      el.style.opacity = 0
                      el.style.transformOrigin = 'left'
                    },
                    enter: function (el, done) {
                      Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
                      Velocity(el, { fontSize: '1em' }, { complete: done })
                    },
                }
    

      

    五、多个元素或组件的过渡动画

    1、多个元素的过渡动画实现

    Html

     <div id="app">
            <transition name="fade" mode="in-out">
                <div v-if="show" key='one'>组件1</div>
                <div v-else key='two'>组件2</div>
            </transition>
            <button @click="handleClick">切换</button>
        </div>
    

      

    style

    <style>
            .fade-enter-active, .fade-leave-active {
              transition: opacity 1s;
            }
            .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
              opacity: 0;
            }
    </style>
    

      注意:这里需要绑定一个key,因为vue会复用,所以不加key就不会有效果。

    2、多个组件的过渡动画实现

    Html

    <div id="app">
            <transition name="fade" >
               <child-one v-if="show"></child-one>
               <child-two v-else></child-two>
            </transition>
            <button @click="handleClick">切换</button>
        </div>
    

      

    js

    <script>
            Vue.component('child-one',{
                template:'<div>child-one</div>'
            })
            Vue.component('child-two',{
                template:'<div>child-two</div>'
            })
            // 1. 创建Vue的实例
            let vm = new Vue({
                el:'#app',
                data:{
                    show:false
                },
                methods:{
                    handleClick:function(){
                        this.show = !this.show
                    }
                }
            });
        </script>
    

      

    css

    <style>
            .fade-enter-active, .fade-leave-active {
              transition: opacity .4s;
            }
            .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
              opacity: 0;
            }
    </style>
    

      

    我们可以通过Vue自带的compoent标签实现动态组件,data中show改成type,type:‘child-one’

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .fade-enter-active, .fade-leave-active {
              transition: opacity .4s;
            }
            .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
              opacity: 0;
            }
    </style>
    
    </head>
    <body>
        <div id="app">
            <transition name="fade" >
                <component :is="type"></component>
              
            </transition>
            <button @click="handleClick">切换</button>
        </div>
    
        <script src="js/vue.js"></script>
        <script>
            Vue.component('child-one',{
                template:'<div>child-one</div>'
            })
            Vue.component('child-two',{
                template:'<div>child-two</div>'
            })
            // 1. 创建Vue的实例
            let vm = new Vue({
                el:'#app',
                data:{
                    type:'child-one'
                },
                methods:{
                    handleClick:function(){
                        this.type = this.type==='child-one'?'child-two':'child-one'
                    }
                }
            });
        </script>
        </body>
        </html>
    

      

    六、Vue中列表的过渡动画

     当我们希望对列表进行过渡效果时,使用transition-group标签就可以了。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            .fade-enter-active, .fade-leave-active {
              transition: opacity 1s;
              color: red;
            }
            .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
              opacity: 0;
            }
    </style>
    
    </head>
    <body>
        <div id="app">
            <transition-group name="fade">
                <div v-for="item in list" key="item.id">{{item.title}}</div>
            </transition-group>
            
            <button @click="handleClick">增加</button>
        </div>
    
        <script src="js/vue.js"></script>
        <script>
            var count = 0
            // 1. 创建Vue的实例
            let vm = new Vue({
                el:'#app',
                data:{
                   list:[]
                },
                methods:{
                    handleClick:function(){
                        this.list.push({
                            id:count++,
                            title:'hello kitty!'
    
                        })
                    }
                }
            });
        </script>
        </body>
        </html>
    

      

    七、动画封装

    我们可以将动画以组件的方式进行封装起来,以后需要使用这个动画时,直接通过插槽将组件放入插槽即可。

    例子:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <script src='js/velocity.min.js'></script>
    
    </head>
    <body>
        <div id="app">
           <fade :show="show">
               <div>
                   hello div
               </div>
           </fade>
           <fade :show="show">
               <h1>hello H1</h1>
           </fade>
            
            <button @click="handleClick">增加</button>
        </div>
    
        <script src="js/vue.js"></script>
        <script>
            Vue.component('fade',{
                props:['show'],
                template:`<transition @before-enter="handleBeforeEnter"
                @enter="handleEnter">
                 <slot v-if="show"></slot>
                </transition>`,
                methods:{
                    handleBeforeEnter:function(el){
                        el.style.color="red"
                    },
                    handleEnter:function(el,done){
                        setTimeout(()=>{
                            Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
                            Velocity(el, { fontSize: '1em' }, { complete: done })
                            done()
                        },2000)
                    }
                }
            })
            // 1. 创建Vue的实例
            let vm = new Vue({
                el:'#app',
                data:{
                   show:false
                },
                methods:{
                    handleClick:function(){
                        this.show=!this.show
                    }
                }
            });
        </script>
        </body>
        </html>
    

      我们这里封装了一个fade组件,通过transition封装一个slot,里面可以支持N个内容。然后将动画效果封装到钩子函数,然后在钩子函数里面放入CSS效果。这样,就将动画效果完全封装在一个组件中了,随时随地可以使用这个带动画的组件啦。

    写了这么多,其实就是开头的四种方式:

    1. 在CSS过渡和动画中自动应用class【默认为fade开头,也可以自定义,不写name时为v开头】
    2. 可以配合使用第三方 CSS 动画库,如 Animate.css【自定义class的方式】
    3. 在过渡钩子函数中使用 JavaScript 直接操作 DOM
    4. 可以配合使用第三方 JavaScript 动画库,如 Velocity.js

     

  • 相关阅读:
    【CF875E】Delivery Club 二分+线段树
    【CF316G3】Good Substrings 后缀自动机
    【BZOJ3413】匹配 离线+后缀树+树状数组
    【BZOJ2658】[Zjoi2012]小蓝的好友(mrx) 平衡树维护笛卡尔树+扫描线
    【BZOJ5133】[CodePlus2017年12月]白金元首与独舞 矩阵树定理
    【LOJ6254】最优卡组 堆(模拟搜索)
    面试问题总结
    Nginx基本配置
    Visual Studio Enterprise 2015下载 Update3
    .net 中生成二维码的组件
  • 原文地址:https://www.cnblogs.com/skyflask/p/10990482.html
Copyright © 2020-2023  润新知