項目開發中動畫有着很重要的做用,並且也是用到的地方很是多,例如:鼠標的進入離開,彈窗效果,組件的顯示隱藏,列表的切換等等,能夠說咱們網頁上的動畫無處不在,也有人說了,這些東西也能夠不使用動畫。css
對,你說的沒錯能夠不使用,可是,首先你要說服你的產品經理咱能不能簡單點,不搞這麼多虛的來點實際的,說完以後我估計大家倆得立馬乾起來,其次,在你的網頁上不使用動畫不夠逼格啊,並且我們的網頁也不夠生動,沒有活力,因而可知動畫的不可或缺性。微信
上面只是開個玩笑,下面我們進入主題,看看 Vue 中如何更好更簡單的添加動畫。ide
首先,Vue 在插入,修改或者移除 DOM 時,提供了多種不一樣的添加動畫的方法,在 Vue 中咱們使用 <transition>
和 <transition-group>
組件時,Vue 會給咱們提供一些內置的 CSS 類與 JS 鉤子函數。函數
先來看看咱們要實現一個什麼樣子的案例效果學習
圖中的例子是一個很是常見的圖片切換效果,不過在這個例子中咱們只是單純的實現圖片的切換,看起來很是的生硬,沒有任何的過渡效果,下面咱們來給圖片加一點動畫的效果,讓它看起來很是的有逼格。動畫
被 <transition>
包裹的組件,在組件的不一樣階段會產生不一樣的 class 類名進行切換this
官網上的一張圖片很是友好的展現了這個切換的過程。
url
v-
是 Vue 中默認的類名前綴,咱們在使用的過程當中若是一直使用默認的命名方式的話,必然會致使一些衝突,因此 Vue 給咱們提供了一個自定義命名的方案,咱們只須要給 <transition>
添加一個 name 屬性便可。spa
既然咱們知道了方法,咱們就來給它加一個簡單的動畫。code
<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 動畫是利用 @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 類名的方法,很是好的支持了與第三方動畫庫的結合。
上面兩個動畫都是咱們本身動手寫出來的,可是有些時候咱們本身手寫的並非那麼完美,或者項目的時間比較緊張,這個時候選擇第三方庫就是一個比較好的方案。咱們繼續利用 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>
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 給咱們提供了兩種過渡模式。
過渡模式只會在相互切換的元素中才會生效
<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 時的場景)添加動畫,喜歡動畫的小夥伴能夠動手去嘗試繪製一些本身喜歡的動畫。
文中若有不足之處,歡迎留言指正,若是本文對你有幫助,歡迎轉發點贊。
關注微信公衆號:六小登登。領取全套學習資源