Vue 教程第九篇—— 動畫和過分效果

過渡效果

SPA 中組件的切換有一種生硬的隱藏顯示感受,爲了更好的用戶體驗,讓組件切換時淡出淡入,Vue 提供了專門的組件 transition。javascript

過濾效果應用場景

  • 條件渲染 (使用 v-if)
  • 條件展現 (使用 v-show)
  • 動態組件
  • 組件根節點

過渡狀態

  • enter:定義進入過渡的開始狀態。在元素被插入時生效。
  • endter-active:定義過渡的狀態。在元素整個過渡過程當中做用,在元素被插入時生效。
  • enter-to: 2.1.8版及以上 定義進入過渡的結束狀態。
  • leave:定義離開過渡的開始狀態。在離開過渡被觸發時生效。
  • leave-active:定義過渡的狀態。在元素整個過渡過程當中做用,在離開過渡被觸發後當即生效。
  • leave-to: 2.1.8版及以上 定義離開過渡的結束狀態。

每一個狀態在使用的時候都是在 CSS 中使用,結合組件 transition 的 name 屬性。如 <transition name="fade"></transition>,對應的是 fade- 加上每一個狀態:fade-entercss

CSS 過渡

使用到組件 transition 的屬性: namehtml

<style type="text/css" media="screen">
    /*初始狀態*/
    .fade-enter{opacity: 0;}
    /*已經準備就緒*/
    .fade-enter-active{transition: all .5s;}
    /*已經消失*/
    .fade-leave-active{opacity: 0; transition: all .5s;}
</style>

<div id="app">
    <input type="button" :value="show ? 'hide' : 'show'" @click="show = !show" />
    <br/>
    <transition name="fade">
        <img src="imgs/green.jpg" v-show="show" />
    </transition>
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            show: true
        }
    })
</script>

效果預覽vue

CSS 動畫

使用到組件 transition 的屬性: namejava

<style type="text/css" media="screen">
    .fade-enter-active{animation: fade-in .5s;}

    .fade-leave-active{animation: fade-out .5s;}

    @keyframes fade-in{
        from{
            opacity: 0;
        }
        to{
            opacity: 1;
        }
    }

    @keyframes fade-out{
        from{opacity: 1;}
        to{opacity: 0;}
    }
</style>

<div id="app">
    <input type="button" :value="show ? 'hide' : 'show'" @click="show = !show" />
    <br/>
    <transition name="fade">
        <img src="imgs/green.jpg" v-if="show" />
    </transition>
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            show: true
        }
    })
</script>

效果預覽git

初始渲染的過濾

第一次加載時的過渡效果,使用到組件 transition 的屬性: appear appear-class appear-active-classgithub

<style type="text/css" media="screen">
    .fade-enter{opacity: 0;}
    .fade-enter-active{transition: all 3s;}
</style>

<div id="app">
    <transition appear appear-class="fade-enter" appear-active-class="fade-enter-active">
        <img src="imgs/green.jpg" />
    </transition>
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app'
    })
</script>

效果預覽app

多個元素的過河效果

同時生效的進入和離開的過渡不能知足全部要求,因此 Vue 提供了 過渡模式:dom

  • in-out:新元素先進行過渡,完成以後當前元素過渡離開。
  • out-in:當前元素先進行過渡,完成以後新元素過渡進入。

使用到組件 transition 的屬性: modeide

<style type="text/css" media="screen">
    .fade-enter{opacity: 0;}
    .fade-enter-active{transition: all .5s;}

    .fade-leave-active{opacity: 0; transition: all .5s;}
</style>

<div id="app">
    <fieldset>
        <legend><h3>mode = in-out</h3></legend>
        <div>
            <input type="button" :value="red ? 'green' : 'red'" @click="red = !red" />
            <br/>
            <transition name="fade" mode="in-out">  
                <img src="imgs/red.jpg" v-if="red" key="red"/>
                <img src="imgs/green.jpg" v-else key="green"/>
            </transition>           
        </div>
    </fieldset>
    <fieldset>
        <legend><h3>mode = out-in</h3></legend>
        <div>
            <input type="button" :value="flag == 1 ? 'green' : flag == 2 ? 'yellw' : 'red'" @click="flag = flag == 1 ? 2 : flag == 2 ? 3 : 1" />
            <br/>
            <transition name="fade" mode="out-in">  
                <img src="imgs/red.jpg" v-if="flag == 1" key="red"/>
                <img src="imgs/green.jpg" v-else-if="flag == 2" key="green"/>
                <img src="imgs/yellow.jpg" v-else key="yellow" />
            </transition>               
        </div>
    </fieldset> 
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            red: true,
            flag: 1
        }
    })
</script>

效果預覽

列表(v-for)的過渡效果

v-for 生成列表過渡效果要使用組件 transition-group,組件提供屬性 tag 表示該組件將會渲染成對應的 DOM 節點,其它的使用和 transition 同樣。

<style type="text/css" media="screen">
    *{list-style: none;}
    li{width: 300px; margin-bottom: 5px; padding: 10px 20px; background-color: #ccc;}

    .list-enter{opacity: 0; transform: translateX(300px);}
    .list-enter-active{transition: all .5s;}

    .list-leave-active{transition: all .5s; opacity: 0; transform: translateX(-300px);}
</style>

<div id="app">
    <p>
        <input type="button" value="AddItem" @click="addItem">
        <input type="button" value="RemoveItem" @click="removeItem">
    </p>
    <transition-group tag="ul" name="list">
        <li v-for="(item, index) in items" :key="item">Item {{index}}</li>
    </transition-group>
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            items: [1,2,3]
        },
        methods: {
            randomIndex: function(){
                return  parseInt(this.items.length * Math.random());
            },
            addItem: function(){
                this.items.splice(this.randomIndex(), 0, this.items.length + 1);
            },
            removeItem: function(){
                this.items.splice(this.randomIndex(), 1);
            }
        }
    })
</script>

效果預覽

自定義過渡的類名

咱們能夠經過如下特性來自定義過渡類名:

  • enter-class
  • enter-active-class
  • enter-to-class (2.1.8+)
  • leave-class
  • leave-active-class
  • leave-to-class (2.1.8+)

他們的優先級高於普通的類名,這對於 Vue 的過渡系統和其餘第三方 CSS 動畫庫,如 Animate.css 結合使用十分有用。

<link rel="stylesheet" type="text/css" href="animate.css">

<div id="app">
    <button @click="show = !show">Toggle render</button>
    <transition enter-active-class="animated jello" leave-active-class="animated bounceOutRight">
        <div v-if="show"><img src="./imgs/green.jpg" /></div>
    </transition>
</div>

<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        data: {
            show: true
        }
    })
</script>

效果預覽

過渡效果鉤子函數

除了用CSS過渡的動畫來實現vue的組件過渡,還能夠用JavaScript的鉤子函數來實現,在鉤子函數中直接操做DOM。咱們能夠在屬性中聲明如下鉤子:

<transition
    v-on:before-enter="beforeEnter"
    v-on:enter="enter"
    v-on:after-enter="afterEnter"
    v-on:enter-cancelled="enterCancelled"
    v-on:before-leave="beforeLeave"
    v-on:leave="leave"
    v-on:after-leave="afterLeave"
    v-on:leave-cancelled="leaveCancelled"
>
</transition>
<script type="text/javascript">
    var vm = new Vue({
        el: '#app',
        methods: {
            // 過渡進入
            // 設置過渡進入以前的組件狀態
            beforeEnter: function (el) {
            // ...
            },
            // 設置過渡進入完成時的組件狀態
            enter: function (el, done) {
            // ...
            done()
            },
            // 設置過渡進入完成以後的組件狀態
            afterEnter: function (el) {
            // ...
            },
            enterCancelled: function (el) {
            // ...
            },
            // 過渡離開
            // 設置過渡離開以前的組件狀態
            beforeLeave: function (el) {
            // ...
            },
            // 設置過渡離開完成時地組件狀態
            leave: function (el, done) {
            // ...
            done()
            },
            // 設置過渡離開完成以後的組件狀態
            afterLeave: function (el) {
            // ...
            },
            // leaveCancelled 只用於 v-show 中
            leaveCancelled: function (el) {
            // ...
            }
        }
    })
</script>
相關文章
相關標籤/搜索