深入理解 Vuejs 动画效果
本文主要?dú)w納在 Vuejs 學(xué)習(xí)過(guò)程中對(duì)于 Vuejs 動(dòng)畫(huà)效果的各個(gè)相關(guān)要點(diǎn)。由于本人水平有限,如文中出現(xiàn)錯(cuò)誤請(qǐng)多多包涵并指正,感謝。如果需要看更清晰的代碼高亮,請(qǐng)?zhí)D(zhuǎn)至我的個(gè)人站點(diǎn)的?深入理解 Vuejs 動(dòng)畫(huà)效果?查看本文。
?
Vue 中的 CSS 動(dòng)畫(huà)原理
將標(biāo)簽外部添加?transition?標(biāo)簽,將其包裹起來(lái)。他的原理圖如下,即當(dāng)一個(gè)元素被transition?包裹之后,Vue 會(huì)自動(dòng)分析元素的 CSS 樣式,然后構(gòu)建一個(gè)動(dòng)畫(huà)流程。
下面示例圖中的線和點(diǎn),就可以稱之為一個(gè)動(dòng)畫(huà)流程。Vue 會(huì)在動(dòng)畫(huà)即將執(zhí)行的瞬間,往內(nèi)部被包裹的的?div?上增添兩個(gè)?class?名,分別是?fade-enter?和?fade-enter-active。當(dāng)動(dòng)畫(huà)第一幀執(zhí)行結(jié)束之后;Vue 會(huì)在動(dòng)畫(huà)執(zhí)行到第二幀的時(shí)候,把之前添加的?fade-enter?這個(gè)?class?去除,然后再增加一個(gè)?fade-enter-to?的?class?名;接著動(dòng)畫(huà)繼續(xù)執(zhí)行,執(zhí)行到結(jié)束的瞬間,Vue 會(huì)把之前添加的?fade-enter-active?和?fade-enter-to?兩個(gè)?class?都去除掉。
當(dāng)動(dòng)畫(huà)從顯示狀態(tài)變?yōu)殡[藏狀態(tài)時(shí),原理圖如下,流程跟上相似:
Vue 過(guò)渡動(dòng)畫(huà)案例代碼
JSbin 預(yù)覽
因?yàn)?transition?上設(shè)置的?name?屬性名為?fade。所以?style?中 CSS 樣式為?fade?開(kāi)頭。如果?transition?上沒(méi)有設(shè)置?name?屬性名,那么style?中 CSS 樣式為?v?開(kāi)頭,即?v-enter、v-center-active?等。
Vue 中使用 CCS3 @keyframes 動(dòng)畫(huà)
JSbin 預(yù)覽
自定義
如果 CSS 樣式?jīng)]有進(jìn)行這種方式命名,而是我們通過(guò)自定義的方式命名的,如下:
.active {transform-origin: left center;animation: bounce-in 1s; } .leave { transform-origin: left center; animation: bounce-in 1s reverse; }那么在?transition?標(biāo)簽里面就要對(duì)這個(gè)自定義的?class?進(jìn)行聲明。
<transition name="fade"enter-active-class="active" leave-active-class="leave" > <div v-if="show"> hello world </div> </transition>?
Animate.css 庫(kù)
Animate.css庫(kù)官網(wǎng)?提供了眾多 CSS 效果。引入和使用的原理和?iconfont?類似。
- 下載該庫(kù)之后,在?link?標(biāo)簽下引入。
- 然后在?transition?標(biāo)簽中定義?enter-active-class?與?leave-active-class?為?animate?庫(kù)中相應(yīng)的樣式。下面示例即是入場(chǎng)動(dòng)畫(huà)使用?swing,出場(chǎng)動(dòng)畫(huà)使用?shake。
JSbin 預(yù)覽
值得注意的是,當(dāng)引入并使用 Animate.css 庫(kù)時(shí),必須使用自定義?class?名的形式使用 Animate.css。同時(shí),class?當(dāng)中必須包含一個(gè)?animated?,然后再將相應(yīng)的效果添加到?animated?之后。
appear
上面一節(jié)的示例中,當(dāng)我們?cè)陧?yè)面剛剛刷新時(shí)(第一次元素顯示時(shí))也加上一些動(dòng)畫(huà)效果,則需要加上?appear?和?appear-active-class?。
<transition name="fade"appear enter-active-class="animated swing" leave-active-class="animated shake" appear-active-class="animated swing" > <div v-if="show"> hello world </div> </transition>JSbin 預(yù)覽
同時(shí)使用過(guò)渡和動(dòng)畫(huà)
之前提到的?Animate.css 庫(kù)?提供的動(dòng)畫(huà)是?@keyframes?類型 CSS3 的動(dòng)畫(huà)。假如我們希望動(dòng)畫(huà)不僅僅只有?@keyframes?的效果,還另外有過(guò)渡的動(dòng)畫(huà)效果時(shí)。這個(gè)時(shí)候我們可以這樣進(jìn)行代碼的編寫(xiě)。
即在?animated?的?class?之后再添加 過(guò)渡動(dòng)畫(huà)的 CSS?class。
.fade-enter,.fade-leave-to {opacity: 0; } .fade-enter-active, .fade-leave-active { transition: opacity 3s; } <transitiontype="transition"name="fade" appear enter-active-class="animated swing fade-enter-active" leave-active-class="animated shake fade-leave-active" appear-active-class="animated swing" > <div v-if="show"> hello world </div> </transition>JSbin 預(yù)覽
動(dòng)畫(huà)執(zhí)行時(shí)長(zhǎng):?值得注意的是,animate?之中的動(dòng)畫(huà)執(zhí)行是 1s,當(dāng)過(guò)渡動(dòng)畫(huà)超過(guò) 1s 時(shí),在?transition?里面添加屬性?type?,就會(huì)以?transition?里面動(dòng)畫(huà)的時(shí)長(zhǎng)為動(dòng)畫(huà)執(zhí)行時(shí)長(zhǎng)。同樣的,這個(gè)執(zhí)行時(shí)長(zhǎng)也可以自定義,通過(guò)?:duration?屬性來(lái)進(jìn)行設(shè)置,例如當(dāng)屬性被設(shè)置為?:duration="10000"?,即時(shí)長(zhǎng)為 10s。除此之外,還可以單獨(dú)設(shè)置出場(chǎng)、入場(chǎng)動(dòng)畫(huà)為不同的時(shí)長(zhǎng),:duration="{ enter: 5000, leave: 10000 }"。
?
Vue 中的 JS 動(dòng)畫(huà)
動(dòng)畫(huà)鉤子
before-enter
before-enter?會(huì)接收到一個(gè)參數(shù)?el?,即指的是動(dòng)畫(huà)?transition?包裹的標(biāo)簽。
<div id="app"><transition name="fade" @before-enter="handleBeforeEnter"> <div v-show="show"> hello world </div> </transition> <button @click="handleClick">切換</button> </div> var vm = new Vue({el: "#app", data: { show: true }, methods: { handleClick: function(){ this.show = ! this.show }, // 接收到一個(gè)參數(shù) el 代指被包裹的標(biāo)簽 handleBeforeEnter: function(el){ el.style.color = 'red' } } })?
enter
enter?會(huì)接收兩個(gè)參數(shù),一個(gè)為?el,指的仍然是動(dòng)畫(huà)?transition?包裹的標(biāo)簽。 一個(gè)為?done,是一個(gè)回調(diào)函數(shù)。
<div id="app"><transition name="fade" @before-enter="handleBeforeEnter" @enter="handleEnter"> <div v-show="show"> hello world </div> </transition> <button @click="handleClick">切換</button> </div> var vm = new Vue({el: "#app", data: { show: true }, methods: { handleClick: function(){ this.show = ! this.show }, handleBeforeEnter: function(el){ el.style.color = 'red' }, handleEnter: function(el, done){ setTimeout(() => { el.style.color = 'green' done() },2000) } } })上面?handleEnter?中的?setTimeout?執(zhí)行完之后,調(diào)用了?done()。而當(dāng)done()?被調(diào)用的時(shí)候,Vue 又會(huì)觸發(fā)一個(gè)?after-enter?事件。
after-enter
after-enter?也要接收到參數(shù)?el?。
<div id="app"><transition name="fade" @before-enter="handleBeforeEnter" @enter="handleEnter" @after-enter="handleAfterEnter" > <div v-show="show"> hello world </div> </transition> <button @click="handleClick">切換</button> </div> var vm = new Vue({el: "#app", data: { show: true }, methods: { handleClick: function(){ this.show = ! this.show }, handleBeforeEnter: function(el){ el.style.color = 'red' }, handleEnter: function(el, done){ setTimeout(() => { // 2s 之后改變顏色 el.style.color = 'green' },2000) setTimeout(() => { // 4s 之后 done() done() },4000) }, handleAfterEnter: function(el){ el.style.color = "#000" } } })?
出場(chǎng)動(dòng)畫(huà)鉤子
相應(yīng)的。出場(chǎng)動(dòng)畫(huà)的鉤子函數(shù)為?before-leave?、leave?和?after-leave?。用法與上面所講的入場(chǎng)動(dòng)畫(huà)鉤子函數(shù)相似。
動(dòng)畫(huà)鉤子示例
JSbin 預(yù)覽
velocity.js 動(dòng)畫(huà)庫(kù)
在?velocityjs 官網(wǎng)?下載?velocity.js?文件。并通過(guò)?script?標(biāo)簽引入?velocity.js。
按照下面的寫(xiě)法,將?el、{opacity: 1}、{duration: 1000, complete: done}?當(dāng)做參數(shù)傳遞給?Velocity?。
var vm = new Vue({el: "#app", data: { show: true }, methods: { handleClick: function(){ this.show = ! this.show }, handleBeforeEnter: function(el){ el.style.opacity = 0 }, handleEnter: function(el, done){ Velocity(el, {opacity: 1}, {duration: 1000, complete: done}) }, handleAfterEnter: function(el){ alert('動(dòng)畫(huà)結(jié)束') } } })JSbin 預(yù)覽
多個(gè)元素與組件的過(guò)渡動(dòng)畫(huà)
多個(gè)元素間過(guò)渡動(dòng)畫(huà)
在下面的示例中,之所以加上?key?值,是為了讓 Vue 不去復(fù)用 DOM,達(dá)到我們想要的效果。給?transition?添加?mode?屬性,out-in?、in-out?分別表示多個(gè)屬性切換時(shí)候的不同的出場(chǎng)、入場(chǎng)順序效果。
<div id="app"><transition mode="out-in" name="fade"> <div v-if="show" key="hello">hello world</div> <div v-else key="bye">Bye World</div> </transition> <button @click="handleClick">切換</button> </div>JSbin 預(yù)覽
多個(gè)組件間過(guò)渡動(dòng)畫(huà)
在下面的示例中,兩個(gè)組件通過(guò)?button?點(diǎn)擊之后觸發(fā)的事件,進(jìn)行內(nèi)容的顯示和隱藏的切換。
.fade-enter,.fade-leave-to {opacity: 0; } .fade-enter-active, .fade-leave-active { transition: opacity 1s; } <div id="app"><transition mode="out-in" name="fade"> <child v-if="show"></child> <child-one v-else></child-one> </transition> <button @click="handleClick">切換</button> </div> Vue.component('child',{template: '<div>child</div>'})Vue.component('child-one',{ template: '<div>child-one</div>' }) var vm = new Vue({ el: "#app", data: { show: true }, methods: { handleClick: function(){ this.show = ! this.show } } })JSbin 預(yù)覽
動(dòng)態(tài)組件
除此之外也可以參考之前?深入理解 Vuejs 組件?中動(dòng)態(tài)組件的方式。給?component?外邊的?transition?添加?mode。
JSbin 預(yù)覽
列表過(guò)渡
參照下面 JSbin 中的示例,構(gòu)造了一段代碼,簡(jiǎn)單的實(shí)現(xiàn)了一個(gè)點(diǎn)擊?button?按鈕添加列表展示數(shù)據(jù)的 demo。現(xiàn)在我們要針對(duì)一整個(gè)列表,在增加或者刪除的時(shí)候?qū)崿F(xiàn)過(guò)渡效果。這里就需要一個(gè)新的標(biāo)簽?transition-group。
添加?transition-group?等同于給每一個(gè)?div?之外添加?transition。相當(dāng)于把列表的過(guò)渡轉(zhuǎn)化成單個(gè)元素標(biāo)簽的過(guò)渡。
除此之外跟前幾節(jié)的過(guò)渡動(dòng)畫(huà)一樣,需要在?style?中添加相應(yīng)的樣式。
JSbin 預(yù)覽
動(dòng)畫(huà)封裝
當(dāng)需要頻繁使用一個(gè)動(dòng)畫(huà)效果的時(shí)候,我們將動(dòng)畫(huà)封裝到一個(gè)組件之中是很好的方法。結(jié)合之前的動(dòng)畫(huà)鉤子,可以實(shí)現(xiàn)將模板、樣式都封裝到組件的效果。當(dāng)需要使用的時(shí)候,直接使用該組件模板標(biāo)簽,并添加相應(yīng)的?show?屬性即可。
<div id="app"><fade :show="show"> <div>hello world</div> </fade> <fade :show="show"> <h1>hello world</h1> </fade> <button @click="handleClick">toggle</button> </div> // 封裝 fade 子組件Vue.component('fade',{props: ['show'], // 接收父組件傳遞過(guò)來(lái)的 show 參數(shù) // template 模板,并使用動(dòng)畫(huà)鉤子將樣式封裝在函數(shù)中 template: ` <transition @before-enter="handleBeforeEnter" @enter="handleEnter" @after-enter="handleAfterEnter"> <slot v-if="show"></slot> </transition> `, methods: { handleBeforeEnter: function(el){ el.style.color = 'red' }, handleEnter: function(el,done){ setTimeout(() => { el.style.color = 'green' },2000) setTimeout(() => { done() },4000) }, handleAfterEnter: function(el){ el.style.color = "#000" } } }) var vm = new Vue({ el: "#app", data: { show: true }, methods: { handleClick: function(){ this.show = ! this.show } } })JSbin 預(yù)覽
轉(zhuǎn)載于:https://www.cnblogs.com/evenyao/p/9643171.html
總結(jié)
以上是生活随笔為你收集整理的深入理解 Vuejs 动画效果的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: c语言,如何产生随机数
- 下一篇: 图灵一代接入V1