Vue中的动画效果

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

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

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

1、单元素/组件的过渡

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

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

一个典型的例子:git

Html文件github

<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文件app

<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>

  

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

实现原理:函数

一、经过使用transition组件后, Vue 将会作如下处理:工具

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

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

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

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

第三帧动画,会去掉全部enter类

 

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

 

2、Vue使用animate.css动画库

一、使用自定义类

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

注意:这里咱们使用了

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注意事项:

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

enter-active-class=""

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

 

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

一、初次动画效果

上面例子中,咱们初次进入的时候没有动画效果,咱们能够作以下修改:

 

 二、若是咱们但愿在上面的例子中还加入一开始咱们说的过渡效果,那该怎么作呢?

 一、由于animate.css有一个本身的动画效果时长,fade也有一个opacity,那么以哪个为准呢?咱们可使用type="transition"来肯定哪一个为准。

二、咱们也能够本身设定动画效果时长样式:duration里面的enter为进入时长,leave为动画离开时长,都是针对过渡效果的。

 

4、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 })
                },
            }

  

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

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

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就不会有效果。

 

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

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>

  

6、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>

  

7、动画封装

咱们能够将动画以组件的方式进行封装起来,之后须要使用这个动画时,直接经过插槽将组件放入插槽便可。

例子:

<!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
相关文章
相关标签/搜索