1. 程式人生 > 實用技巧 >vue 過渡

vue 過渡

vue過渡

vue在插入、更新或者移除DOM時,提供了多種不同方式的應用過渡效果,下面主要總結一些常用的過渡。

單元素過渡(vue1.0)

我們常用的動畫是css3的動畫,在vue中依舊有效。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="bower_components/vue/dist/vue.js"></script>
    <style>
        #div1{
            width:100px;
            height:100px;
            background: red;
        }
        .fade-transition{
            transition: 1s all ease;    
        }
        .fade-enter{
            opacity: 0;
        }
        .fade-leave{
            opacity: 0;
            transform: translateX(200px);
        }
    </style>
</head>
<body>
    <div id="box">
        <input type="button" value="按鈕" @click="toggle">
        <div id="div1" v-show="bSign" transition="fade"></div>
    </div>

    <script>
        new Vue({
            el:'#box',
            data:{
                bSign:true
            },
            methods:{
                toggle(){
                    this.bSign=!this.bSign;
                }
            }
        });
    </script>
</body>
</html>

在上面的例子中,我們實現了一個進入和離開的動畫效果,我們需要做如下幾步:

  • 在需要使用動畫的元素中新增名稱,即上面的div中新增transition="fade"
  • 根據新增的名稱為元素新增class類實現動畫效果,這些類必須以上一步總的名稱開頭
  • 借用v-show進行條件展示
  • 通過事件觸發動畫

過渡元件(vue2.0)

除了上面為元素新增動畫名稱的方式實現過渡外,vue還提供了transition的封裝元件,在下列情況中,可以黑任何元素和元件新增進入或離開的過渡效果:

  • 條件渲染(v-if)
  • 條件展示(v-for)
  • 動態元件
  • 元件跟節點
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <script src="bower_components/vue/dist/vue.js"></script>
    <style>
        .fade-enter-active, .fade-leave-active {
            transition: opacity .5s;
        }
        .fade-enter, .fade-leave-to {
            opacity: 0;
        }
    </style>
</head>
<body>
    <div id="box">
        <button v-on:click="show = !show">Toggle</button>
        <transition name="fade">
            <p v-if="show">hello</p>
        </transition>
    </div>

    <script>
        new Vue({
            el:'#box',
            data: {
                show: true
              }    
        });
    </script>
</body>
</html>

在上面的例子中,我們將需要實現動畫效果的元素包裹在transition元件中,vue會自動嗅探目標元素是否應用了css過渡或動畫,如果是,則會在恰當的時機新增或刪除css類名。

過渡元件類名

vue在進入/離開的過渡中提供了6個可供選擇的class切換,下面的例子我們只使用到了4個,關於6個類名的使用,在官方文件中詳細說明。

  • fade-enter:初始狀態
  • fade-enter-active:元素顯示出來的狀態(變化成什麼樣子)
  • fade-leave:同fade-enter
  • fade-leave-active:元素消失離開的狀態
<!DOCTYPE html>
<html lang="en">
<head>
   <title>vue</title>
    <style>
        p{
            width:300px;
            height:300px;
            background: red;
        }
        .fade-enter-active, .fade-leave-active{
            transition: 1s all ease;
        }

        .fade-enter-active{
            opacity:1;
            width:300px;
            height:300px;
        }
        .fade-leave-active{
            opacity:0;
            width:100px;
            height:100px;
        }

        .fade-enter,.fade-leave{
            opacity:0;
            width:100px;
            height:100px;
        }
    </style>
    <script src="vue.js"></script>
    <script>
        window.onload=function(){
            new Vue({
                el:'#box',
                data:{
                    show:false
                }
            });
        };
    </script>
</head>
<body>
    <div id="box">
        <input type="button" value="點選顯示隱藏" @click="show=!show">

        <transition name="fade">
            <p v-show="show"></p>
        </transition>
    </div>
</body>
</html>

需要說明的是,因為我們在transition元件中為此元件添加了一個名稱name="fade",所以我們的類名都是以該名稱開頭的,同上一個例子一樣需要保持一致,但是這個元件名稱不是必須的,所以我們也可以不用為元件新增名稱,那麼此時的類名就需要以v-開頭,即上面的.fade-enter就需要換成v-enter了。

過渡元件相關函式

在使用過渡元件實現動畫時,為了能更好的實現想要的動畫效果,vue2.0中針對動畫的不同狀態給出了不同的動畫函式,並且每個函式都接收一個代表當前運動元素的引數。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <style>
        p{
            width:200px;
            height:200px;
            background: red;
        }
        .fade-enter-active, .fade-leave-active{
            transition: 1s all ease;
        }

        .fade-enter-active{
            opacity:1;
            width:200px;
            height:200px;
        }
        .fade-leave-active{
            opacity:0;
            width:100px;
            height:100px;
        }

        .fade-enter,.fade-leave{
            opacity:0;
            width:100px;
            height:100px;
        }
    </style>
    <script src="vue.js"></script>
    <script>
        window.onload=function(){
            new Vue({
                el:'#box',
                data:{
                    show:false
                },
                methods:{
                    beforeEnter(el){
                        console.log('動畫enter之前');
                    },
                    enter(el){
                        console.log('動畫enter進入');
                    },
                    afterEnter(el){
                        console.log('動畫進入之後');
                        el.style.background='blue';
                    },
                    beforeLeave(el){
                        console.log('動畫leave之前');
                    },
                    leave(el){
                        console.log('動畫leave');
                    },
                    afterLeave(el){
                        console.log('動畫leave之後');
                        el.style.background='red';
                    }
                }
            });
        };
    </script>
</head>
<body>
    <div id="box">
        <input type="button" value="點選顯示隱藏" @click="show=!show">

        <transition name="fade"
            @before-enter="beforeEnter"
            @enter="enter"
            @after-enter="afterEnter"

            @before-leave="beforeLeave"
            @leave="leave"
            @after-leave="afterLeave"
        >
            <p v-show="show"></p>
        </transition>
    </div>
</body>
</html>

過渡元件之多個元素

和單一的過渡元件不同的是,多個元素的過渡元件使用的是transition-group,並且需要給元件內的多個元素新增一個key用作識別符號,如下所示:

但是更多的時候,這個key是迴圈出來的。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue</title>
    <style>
        p{
            width:80px;
            height:30px;
            background: red;
            margin:10px auto;
            text-align: center;
        }
    </style>
    <script src="vue.js"></script>
    <link rel="stylesheet" href="animate.css">
</head>
<body>
    <div id="box">
        <input type="text" v-model="show">
        <transition-group enter-active-class="zoomInLeft" leave-active-class="zoomOutRight">
            <p v-show="show" class="animated" v-for="(val,index) in lists" :key="index">
                {{val}}
            </p>
        </transition-group>
    </div>
    <script>
        new Vue({
            el:'#box',
            data:{
                show:'',
                list:['apple','banana','orange','pear']
            },
            computed:{
                lists:function(){
                    var arr=[];
                    this.list.forEach(function(val){
                        if(val.indexOf(this.show)!=-1){
                            arr.push(val);
                        }
                    }.bind(this));
                    return arr;
                }
            }
        });
    </script>
</body>
</html>

css動畫庫

Animate.css是一款常見的動畫庫,在html中經常被使用,我們在vue1.0中依舊可以通過引用的方式使用。

在使用第三方動畫庫的時候,我們還是和上面的例子一樣通過新增類名來實現動畫,只是這裡的類名不再是我們自己寫的類,而是直接使用第三庫中的類名,這裡稍微做了一點改變的是,我們是在vue中添加了一個transitions,然後將所有的動畫名稱集中寫在了這個裡面而已。

首先需要為元素新增一個class類為:class="animated",然後再新增動畫名稱transition="bounce",最後根據動畫名稱進行定義相關動畫類。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="bower_components/vue/dist/vue.js"></script>
    <link rel="stylesheet" href="bower_components/animate.css/animate.css">
    <style>
        #box{
            width:400px;
            margin: 0 auto;
        }
        #div1{
            width:100px;
            height:100px;
            background: red;
        }
    </style>
</head>
<body>
    <div id="box">
        <input type="button" value="按鈕" @click="toggle">
        <div id="div1" class="animated" v-show="bSign" transition="bounce"></div>
    </div>

    <script>
        new Vue({
            el:'#box',
            data:{
                bSign:true
            },
            methods:{
                toggle(){
                    this.bSign=!this.bSign;
                }
            },
            transitions:{ //定義所有動畫名稱
                bounce:{
                    enterClass:'zoomInLeft',
                    leaveClass:'zoomOutRight'
                }
            }
        });
    </script>
</body>
</html>

但是在vue2.0中,使用上稍微有點不同,具體的有兩種實現方式,分別如下所示: