Vue Transition
竹白的 Vue.js 學習筆記
Vue 提供了 transition
的封裝元件,在下列情形中,可以給任何元素和元件添加進入/離開的轉場效果:
v-if
或 v-show
)先看一個簡單的基本範例:
<button v-on:click="show = !show">Toggle</button>
<transition>
<div class="box" v-if="show">2</div>
</transition>
data: {
show: true,
},
.v-enter, .v-leave-to {
opacity: 0;
}
.v-leave, .v-enter-to {
opacity: 1;
}
.v-enter-active,
.v-leave-active {
transition: opacity 1s;
}
當我們使用 transition
元件將元素包住,Vue 會做以下處理:
transition/animation
如果是,在恰當的時機添加/刪除 CSS 類別名稱。transition
元件提供了 JavaScript 鉤子函式,這些鉤子函式將在恰當的時機被呼叫。transition/animation
,DOM 操作 (插入/刪除) 在下一幀中立即執行。transition
元件共提供了,六種類別名稱提供切換。
進場:
v-enter
:定義進場的開始狀態。
v-enter-active
:定義進場生效時的狀態,在整個進場的階段中應用。
transition/animation
完成之後移除v-enter-to
:2.1.8版及以上 定義進場的結束狀態。
v-enter
被移除),在 transition/animation
完成之後移除離場:
v-leave
:定義離場的開始狀態。
v-leave-active
:定義離場生效時的狀態,在整個離場的階段中應用。
transition/animation
完成之後移除v-leave-to
:2.1.8版及以上 定義離場的結束狀態。
v-leave
被移除),在 transition/animation
完成之後移除通常會設定 v-enter
與 v-leave-active
相同的效果、v-leave
與 v-enter-to
相同的效果,達到同尾相接形成一個循環,而 v-enter-to
與 v-leave-to
會用來設定轉場時間或動畫。
enter-to
預設 opacity: 1
、transform: none
,所以不一定要設定。
transition
transition
元件預設使用上述 v-
前綴的類別名稱。請參考一開始基本範例。
因為不可能只用一種動態效果,因此使用自訂義的前綴,需要加上 name
特性,舉例來說,<transition name="fade">
,套用的那麼類別名稱的前綴就會是 fade-enter
。
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<div class="box" v-if="show"></div>
</transition>
設定一個進場由透明度 0 變 1 並由右測 100px
處滑入,並且進場、離場分別設定不同的曲線函數:
.fade-enter,
.fade-leave-to {
opacity: 0;
transform: translateX(100px);
}
.fade-leave, .fade-enter-to {
opacity: 1;
}
.fade-enter-active {
transition: all 0.3s ease;
}
.fade-leave-active {
transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}
再舉一個例子,由下往上進場,由右出場:
.fade-enter {
opacity: 0;
transform: translateY(100%);
}
.fade-enter-to, .fade-leave {
opacity: 1;
}
.fade-leave-to {
opacity: 0;
transform: translateX(100%);
}
.fade-enter-active,.fade-leave-active {
transition: all 0.8s ease;
}
animation
CSS animation
用法同 CSS transition
,區別是在動畫中 v-enter
類名在節點插入 DOM 後不會立即刪除,而是在 animationend
事件觸發時刪除。
.bounce-enter-active {
animation: bounce-in 0.5s;
}
.bounce-leave-active {
animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
我們可以通過以下 transition
元件特性來使用自訂義類別名稱:
enter-class
enter-active-class
enter-to-class
2.1.8+leave-class
leave-active-class
leave-to-class
2.1.8+他們的優先級高於普通的類別名稱。
舉個簡單得範例,來說明使用方式:
.opacity-0 {
opacity: 0;
}
.trs-time-3 {
transition-duration: 3s;
}
<transition
enter-class="opacity-0"
leave-to-class="opacity-0"
enter-active-class="trs-time-3"
leave-active-class="trs-time-3"
>
<div class="box" v-if="show"></div>
</transition>
自訂義類別名稱,對於套用第三方 CSS 動畫庫結合非常方便。
舉例來說,使用 Animate.css 的動畫效果:
<button v-on:click="show = !show">
Toggle
</button>
<transition
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<div class="box" v-if="show"></div>
</transition>
<transition
enter-active-class="animated fadeInUp"
leave-active-class="animated flipInY"
>
<div class="box" v-if="show"></div>
</transition>
或者是 magic.css:
<button v-on:click="show = !show">
Toggle
</button>
<transition
enter-active-class="magictime foolishIn"
leave-active-class="magictime tinDownOut"
>
<div class="box" v-if="show"></div>
</transition>
transition/animation
Vue 為了知道轉場的完成,必須設置相應的事件監聽器。它可以是 transitionend
或 animationend
,這取決於給元素應用的 CSS 規則。如果你使用其中任何一種,Vue 能自動識別類型並設置監聽。
但有時候會遇到需要同時設置的情況,但兩邊的完成時間不一致,這時候就需要手動設置 transitionend
或 animationend
來明確告知 Vue 要監聽的類型。
舉例來說,假設你分別使用自訂義的類別名稱和 Animate.css :
.fade-enter,.fade-leave-to {
opacity: 0;
}
.fade-enter-to, .fade-leave {
opacity: 1;
}
.fade-enter-active,.fade-leave-active {
transition: opacity 3s;
}
<transition
name="fade"
type="transition"
enter-active-class="animated swing fade-enter-active"
leave-active-class="animated bounce fade-leave-active"
>
<div class="box" v-if="show"></div>
</transition>
這裡要注意,使用自訂義類別名稱優先度大於普通的類別名稱,所以fade-enter-active
和 fade-leave-active
記得要補上。
Animate.css 預設動畫時間為 1s,而我們設置的 transition
時間為 3s,Animate.css 的動畫很外就觸發完成了,而轉場還沒結束。在很多情況下,Vue 可以自動得出轉場效果的完成時機,但還是有可能出現例外。
為了避免出現例外,你就需要手動設定 type="transition"
以 transition
的時間為準。反之動畫時間大於轉場就以動畫時間為準。
上面已經提過了,在很多情況下,Vue 可以自動得出轉場效果的完成時機。預設情況下,Vue 會等待其在轉場效果的根元素的第一個 transitionend
或 animationend
事件。
但在某些情況下,還可以自定義整個動態效果總時間長,使用的是 duration
特性搭配 v-bind
。
舉例來說,總時常為 5s:
<transition :duration="5000">...</transition>
也可以分別設定進入和移除持續時間:
<transition :duration="{ enter: 500, leave: 800 }">...</transition>
這是一個 transition
需要 5秒,但總轉場時間強制設為 1秒的範例:
透過設定 appear
特性,設置節點在初始渲染的轉場。
<transition appear>
<!-- ... -->
</transition>
CodePen,載入畫面時,會有進場效果。
appear
預設使用進場的類別,如果要與進場套用不同的動畫效果,需要使用自定義的類別名稱:
<transition
appear
appear-class="custom-appear-class"
appear-to-class="custom-appear-to-class" (2.1.8+)
appear-active-class="custom-appear-active-class"
>
<!-- ... -->
</transition>