Vue 封裝好的 transition 元件提供開發者在插入、更新、移除 DOM 時,添加動畫轉場的效果。它提供三種應用方式:
使用條件
- 使用
v-if - 使用
v-show - 動態元件 (Dynamic Components),如使用
:is,透過字串變數進行元件切換 - 元件的根節點(Component Root Nodes)
方法1 - CSS 轉場 & CSS 動畫
預設的轉場類名
使用 <transition> 時,Vue 會在特定時間點將對應的 class 加到元素中,然後再移除,產生進入和離開的漸變效果。
v-enter
進入轉場開始的狀態。在元素插入前生效,在元素被插入後的下一幀移除v-enter-active
進入轉場過程的狀態。在整個進入轉場的階段中應用,在轉場完成之後移除。在這裡可以定義轉場的過程時間,延遲。如:transition: opacity .5sv-enter-to
進入轉場結束的狀態。在元素被插入之後下一幀生效(與此同時 v-enter 被移除),在轉場完成之後移除 (2.1.8版以上)v-leave
離開轉場的開始狀態。在離開轉場被觸發時立即生效,下一幀被移除v-leave-active
離開轉場生效時的狀態。在整個離開轉場的階段中應用,在轉場完成之後移除。在這裡可以定義轉場的過程時間,延遲。如:transition: opacity .5sv-leave-to
離開轉場結束的狀態。在v-leave被觸發之後下一幀生效(與此同時 v-leave 被移除),在轉場完成之後移除 (2.1.8版以上)

來源: Vue 官方文件
若無自行定義類別的前綴詞,預設是 v- (如上)。若有自行定義需求,則可以在 <transition> 標籤添加 name 屬性,並且將預設類別 v- 的 v 改為自定義名稱。
CSS 轉場
1 | <div id="demo"> |
1 | new Vue({ |
1 | .fade-enter-active, .fade-leave-active { |
See the Pen RzeYmR by Dylan (@dylan_demo) on CodePen.
流程敘述
- 第一次點擊按鈕,變數
show被更改為false,此時元素移除,同時觸發leave→leave-active→leave-to - 第二次點擊按鈕,變數
show被更改為true,此時元素插入,同時觸發enter→enter-active→enter-to
另外 v-if 也可以改為 v-show,後者並不會移除元素,而是以 display: block 和 display: none 做切換。
CSS 動畫
使用 CSS animation 和 CSS transition 基本上沒有太大差異,區別是在動畫中 v-enter 在節點插入 DOM 後不會立即刪除,而是在 animationend 事件觸發時刪除。
1 | <div id="demo"> |
1 | new Vue({ |
1 | .bounce-enter-active { |
See the Pen qzJMzB by Dylan (@dylan_demo) on CodePen.
方法2 - 搭配第三方動畫套件 (Animate.css)
客製化的方式除了方法一之外,Vue 也提供了另外一種方式。我們可以直接在 <transition> 標籤內插入屬性,值則為第三方庫寫好的 Class Name。以下範例使用 Animate.css 動畫庫做範例。
預設的轉場屬性
我們可以通過以下屬性來自定義轉場類名,時間點可以對應到上面提到的預設的轉場類名:
enter-classenter-active-classenter-to-class(2.1.8+)leave-classleave-active-classleave-to-class(2.1.8+)
範例
1 | <div id="demo"> |
1 | new Vue({ |
See the Pen XLxPLG by Dylan (@dylan_demo) on CodePen.
方法3 - JavaScript 鉤子函式
另一種方法則是在 <transition> 元素行內綁定鉤子,可以搭配 CSS 轉場和 CSS 動畫使用,也可單獨使用。
預設鉤子
beforeEnter(el)
進入轉場/動畫前啟動enter(el, callback)
進入轉場/動畫之元素插入時啟動。done callback則在結束時呼叫,可傳可不傳。
與方法2所對應的時間點為enter-classafterEnter(el)
進入轉場/動畫時啟動。
與方法2所對應的時間點為enter-to-classenterCancelled(el)
在未完成進入轉場/動畫時取消動作。beforeLeave(el)
離開轉場/動畫前啟動leave(el, callback)
離開轉場/動畫之元素插入時啟動。done callback則在結束時呼叫,可傳可不傳。
與方法2所對應的時間點為leave-classafterLeave(el)
離開轉場/動畫時啟動。leaveCancelled(el)
在未完成離開轉場/動畫時取消動作。
與方法2所對應的時間點為leave-to-class
補充:當只用JavaScript 轉場的時候,在enter和leave中必須使用done進行callback。否則,它們將被同步呼叫,轉場會立即完成。
補充:推薦對於僅使用 JavaScript 轉場的元素添加
:css="false",Vue 會跳過 CSS 的檢測。這也可以避免過渡過程中 CSS 的影響。
範例
一個使用 Velocity.js 函式庫的簡單例子:
1 | <div id="demo"> |
1 | new Vue({ |
See the Pen YoJJKq by Dylan (@dylan_demo) on CodePen.
兩個元素的過場動畫
透過 v-if 同時讓兩個元素進行過場。
1 | <div id="demo"> |

我們會發現,在動畫執行階段兩個元素會在同個時間交集,造成空間互相擠壓的問題。這並不是我們想要的結果。
而 Vue 的 transition 元件提供了一個解法,我們可以為 transition 標籤加上另一個屬性 mode。
in-out: 新的元素先執行enter,待完成後舊元素才執行leaveout-in:舊元素先執行leave,待完成後新元素才執行enter(一般符合預期的狀況)
稍作修改
1 | <transition name="fade" mode="out-in"> |

另外有一點需要特別注意,剛剛的例子使用的是兩個不同元素(h1及h2),是可以正常執行的,但是如果兩個元素是相同的就會出現一些問題。
1 | <div id="demo"> |

我們可以為 transition 標籤加上 key,來解決這個問題,key 內的值需要是唯一值,即每個元素的值不可重複,如此 Vue 才能判斷它為不同的元素,進而正常執行過場。
1 | <div id="demo"> |
See the Pen ydRRPr by Dylan (@dylan_demo) on CodePen.
多個元素的過場
前面的例子都是使用 v-if 來做過場效果,最多只有兩個元素,如果使用 v-for 產生的大量元素就必須使用 transition-group 元件。
transition-group 在編譯後預設會被轉換成 span 標籤,由這個標籤包住所有 v-for 渲染出來的元素。例如:
1 | <transition-group name="fade"> |
編譯結果為:
1 | <span> |
我們可以透過 tag 屬性將預設標籤改掉
1 | <transition-group name="fade" tag="div"> |
編譯結果為:
1 | <div> |
注意:和
transition元件一樣,在transition-group的元素也必須為它加上key
使用 bootstrap 卡片元件來製作一個簡易的新增刪除功能的表單,並且使用 <transition-group> 加上動畫效果吧。
1 | <div id="demo"> |
1 | let app = new Vue({ |
See the Pen Rzevvx by Dylan (@dylan_demo) on CodePen.
重複利用動畫效果
可以使用元件及插槽(Slot)封裝你精心設計的動畫效果,下個專案可以重複利用,這邊使用上面卡片的範例來做。
1 | <div id="demo"> |
1 | // 區域元件 (二擇一) |
See the Pen MMzGYp by Dylan (@dylan_demo) on CodePen.
參考資料
Vue 官方文件
Vue.js (14) - 過場效果及動畫
Vue.js: 樣式與漸變 Transitions
Vue.js: 動畫 Animations
Vue.js: 進階過渡效果