Vue一個案例引發「動畫」的使用總結
專案開發中動畫有著很重要的作用,而且也是用到的地方非常多,例如:滑鼠的進入離開,彈窗效果,元件的顯示隱藏,列表的切換等等,可以說我們網頁上的動畫無處不在,也有人說了,這些東西也可以不使用動畫。
對,你說的沒錯可以不使用,但是,首先你要說服你的產品經理咱能不能簡單點,不搞這麼多虛的來點實際的,說完之後我估計你們倆得立馬乾起來,其次,在你的網頁上不使用動畫不夠逼格啊,而且咱們的網頁也不夠生動,沒有活力,由此可見動畫的不可或缺性。
上面只是開個玩笑,下面咱們進入主題,看看 Vue 中如何更好更簡單的新增動畫。
首先,Vue 在插入,修改或者移除 DOM 時,提供了多種不同的新增動畫的方法,在 Vue 中我們使用 <transition>
<transition-group>
元件時,Vue 會給我們提供一些內建的 CSS 類與 JS 鉤子函式。
先來看看我們要實現一個什麼樣子的案例效果
圖中的例子是一個非常常見的圖片切換效果,不過在這個例子中我們只是單純的實現圖片的切換,看起來非常的生硬,沒有任何的過渡效果,下面我們來給圖片加一點動畫的效果,讓它看起來非常的有逼格。
CSS 過渡
被 <transition>
包裹的元件,在元件的不同階段會產生不同的 class 類名進行切換
- v-enter/v-leave:動畫的第一幀
- v-enter-acive/v-leave-active:動畫執行的階段,一些過渡屬性會放置在這裡,如:時間,延遲等
- v-enter-to/v-leave-to:動畫結束,最後一幀
官網上的一張圖片非常友好的展示了這個切換的過程。
v-
是 Vue 中預設的類名字首,我們在使用的過程中如果一直使用預設的命名方式的話,必然會導致一些衝突,所以 Vue 給我們提供了一個自定義命名的方案,我們只需要給 <transition>
新增一個 name 屬性即可。
既然我們知道了方法,我們就來給它加一個簡單的動畫。
<template>
<ul class="tabs-list">
<li
v-for="tab in tabs"
:key="tab.id"
:class="{active: tabOn === tab.id}"
>
<a
@mouseover="tabOn = tab.id"
:href="tab.url" target="_blank"
>
{{tab.name}}
<transition name="flip">
<img v-show="tabOn === tab.id" :src="tab.imgUrl">
</transition>
</a>
</li>
</ul>
<template>
<style lang="scss" scoped>
.flip-enter-active {
transition: transform 1s;
}
.flip-leave-active {
transition: transform 1s;
}
.flip-enter,
.flip-leave-to {
transform: scaleY(0);
}
</style>
複製程式碼
CSS 動畫
與上面 CSS 過渡不同的是,我們這裡說的 CSS 動畫是利用 @keyframes 來建立與上面類似的動畫效果。
<style lang="scss" scoped>
@keyframes scaleY-in {
0% {
transform: scaleY(0);
}
50% {
transform: scaleY(0.5);
}
100% {
transform: scaleY(1);
}
}
.flip-enter-active {
animation: scaleY-in 1s;
}
.flip-leave-active {
animation: scaleY-in 1s reverse;
}
</style>
複製程式碼
使用第三方動畫庫
Vue 中給我們提供了自定義 CSS 類名的方法,非常好的支援了與第三方動畫庫的結合。
- enter-class / leave-class
- enter-active-class / leave-active-class
- enter-to-class / leave-to-class
上面兩個動畫都是我們自己動手寫出來的,但是有些時候我們自己手寫的並不是那麼完美,或者專案的時間比較緊張,這個時候選擇第三方庫就是一個比較好的方案。我們繼續利用 Animate.css 動畫庫修改我們上面的例子。
<transition
name="flip"
enter-active-class="animated rotateIn"
leave-active-class="animated rotateOut"
>
<img v-show="tabOn === tab.id" :src="tab.imgUrl">
</transition>
複製程式碼
JavaScript 動畫
Vue 中還給我們提供了一些鉤子函式,我們可以使用 JavaScript 鉤子函式構建動畫。
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@enter-cancelled="enterCancelled"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave"
@leave-cancelled="leaveCancelled"
:css="false"
>
</transition>
複製程式碼
所有鉤子都會傳入一個 el(元素)引數,enter/leave 函式還會傳入一個 done 函式作為引數。它會告知我們的動畫完成,我們綁定了 css 為 false,告訴元件跳過 CSS 的檢測,使用 JavaScript。
我們結合 Velocity.js 動畫,來修改完成我們的動畫效果。
<transition
@enter="enter"
@leave="leave"
:css="false"
>
<img v-show="tabOn === tab.id" :src="tab.imgUrl">
</transition>
<script>
methods: {
enter(el, done) {
Velocity(el, { scaleY: "0" });
Velocity(el, { scaleY: "0.5" }, { duration: 1000 });
Velocity(el, { scaleY: "1" }, { complete: done });
},
leave: function(el, done) {
Velocity(el, { scaleY: "1" });
Velocity(el, { scaleY: "0.5" }, { duration: 1000 });
Velocity(el, { scaleY: "0" }, { complete: done });
}
}
</script>
複製程式碼
過渡模式
我們再來回頭看看上面的例子,不管我們使用何種方式實現的動畫,你會發現一個問題就是,動畫在切換的時候兩者(進入/離開)是同時進行的,有些時候,我們並不希望產生這種效果,對我們的動畫效果非常的不友好,比如我們看看下面的這個例子。
<template>
<div class="translate-container" @click="clickHandler">
<transition name="slide">
<img v-if="isShow" src="./feature/03.jpg" key="first">
<img v-else src="./feature/04.jpg" key="second">
</transition>
</div>
</template>
<script>
export default {
methods: {
clickHandler() {
this.isShow = !this.isShow;
}
}
}
</script>
<style lang="scss" scoped>
.slide-enter-active,
.slide-leave-active {
transition: all 0.5s;
}
.slide-leave-to,
.slide-enter {
transform: scaleY(0);
}
</style>
複製程式碼
很顯然,這種是非常不好的效果,值得高興的是 Vue 中給我們提供了一個解決方案-- 過渡模式,我們不需要增加額外的程式碼,只需要修改下特性即可。
Vue 給我們提供了兩種過渡模式。
- in-out:新元素先進行過渡,完成之後當前元素過渡離開。
- out-in:當前元素先進行過渡,完成之後新元素過渡進入
過渡模式只會在相互切換的元素中才會生效
<transition name="fade" mode="out-in"></transition>
<transition name="fade" mode="in-out"></transition>
複製程式碼
下面我們就用過渡模式修改我們上面的案例。
<transition name="slide" mode="out-in">
<img v-if="isShow" src="./feature/03.jpg" key="first">
<img v-else src="./feature/04.jpg" key="second">
</transition>
複製程式碼
總結
Vue 給我們提供了比較直觀靈活的 API,方便我們在專案中新增動畫的效果。
Vue 中除了這些單元素的動畫以外還提供了<transition-group>
給我的列表(使用v-for 時的場景)新增動畫,喜歡動畫的小夥伴可以動手去嘗試繪製一些自己喜歡的動畫。
文中如有不足之處,歡迎留言指正,如果本文對你有幫助,歡迎轉發點贊。