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
相關文章
相關標籤/搜索