大家好!今天要聊的是 Vue.js 的 Transition Hooks
,這些小巧的鉤子不僅能讓網頁切換更順暢,還能在動效進行時插入各種巧妙的處理。
你是不是也曾遇過頁面切換時,背景突然閃白的尷尬情況?
沒關係,這篇文章不僅會帶你認識 Vue 的鉤子們,還會教你如何用實際案例解決這些常見問題,讓你的網頁更迷人、更專業!
準備好讓你的動態效果升級嗎?
我們一起來看看吧!
在上一篇的文章範例中,Day06 Vue.js 簡單迷人的網頁動態效果 - 過渡類別篇
我們就有使用過渡模式
,來搭配往左滑的換頁效果,這次我們改採用往上滑頁效果的方式來繼續說明。
<template>
<div :class="['relative w-full h-screen overflow-hidden', containerBgColor]">
<transition name="slide" mode="out-in">
<component :is="getComponent" @change-page="changePage" />
</transition>
</div>
</template>
<style scoped>
/* 調整進場與離場動效為上下方向 */
.slide-enter-from {
transform: translateY(100%); /* 從下方進場 */
}
.slide-enter-active,
.slide-leave-active {
position: absolute;
width: 100%;
transition: transform 0.5s ease; /* 過渡時間與緩動 */
}
.slide-leave-to {
transform: translateY(-100%); /* 向上滑出 */
}
.slide-enter-to,
.slide-leave-from {
transform: translateY(0); /* 元素在正中間位置 */
}
</style>
在過渡效果中,過渡模式(Transition Mode)
決定了鉤子的執行順序,直接影響動效的協調與體驗。
mode="in-out"
:先完成進場動效,再執行離場動效。適合強調新內容的模式。mode="out-in"
:先完成離場動效,再執行進場動效。適合先清除舊內容的場景。在使用 mode="out-in"
或 mode="in-out"
時,這兩個模式是互相排斥的,可以根據具體的過場需求來選擇,因為這兩種模式會有不同的視覺體驗效果。
我們使用 mode="in-out"
做 Page Transition 時,換頁過程中常見的「畫面閃白」問題,我們的處理方法很簡單——先存下當前頁面的背景色,下一次換頁時直接延續這個顏色!
這樣就不會出現突然空白的突兀感,換頁自然又順暢呢
<Transition
@before-enter="onBeforeEnter"
@enter="onEnter"
@after-enter="onAfterEnter"
@enter-cancelled="onEnterCancelled"
@before-leave="onBeforeLeave"
@leave="onLeave"
@after-leave="onAfterLeave"
@leave-cancelled="onLeaveCancelled"
>
<!-- ... -->
</Transition>
Vue 3 的 <transition>
元件提供了一系列的生命周期 hooks,用於在元素進場和離場的過程中掛鉤特定的操作。
這些 hooks 可以讓你在動效的不同階段執行自定義的邏輯。
@before-enter="onBeforeEnter"
(進場前):
@enter="onEnter"
(進場中):
@after-enter="onAfterEnter"
(進場後):
@enter-cancelled="onEnterCancelled"
(進場取消):
進場範例與實作程式碼
<script lang="ts" setup>
import { ref } from "vue";
const onBeforeEnter = () => {
console.log(" @before-enter 進場動效開始了!");
};
// _el 忽略的參數表示我們知道這個參數存在但暫時不使用
// 這個參數仍然需要保留,因為它是 Vue Transition 鉤子的標準參數定義
const onEnter = (_el: Element, done: () => void) => {
console.log(" @enter 進場動效活動!");
done(); // 確保調用 done() 以通知 Vue 動效已完成
};
const onAfterEnter = () => {
console.log(" @after-enter 進場動效已完成!");
};
// 控制元素顯示狀態
const show = ref(false);
</script>
<template>
<div class="flex flex-col gap-4 mx-auto p-4 space-y-4">
<button @click="show = !show" class="px-4 py-2 bg-blue-500 text-white text-10 rounded">
進場動效範例觸發
</button>
<!-- 元素 1: 使用 before-enter -->
<transition @before-enter="onBeforeEnter" :key="1">
<div v-if="show" class="p-4 bg-yellow-200 rounded shadow">
元素 1: @before-enter
</div>
</transition>
<!-- 元素 2: 使用 enter -->
<transition @enter="onEnter" :key="2">
<div v-if="show" class="p-4 bg-green-200 rounded shadow">元素 2: @enter</div>
</transition>
<!-- 元素 3: 使用 after-enter -->
<transition @after-enter="onAfterEnter" :key="3">
<div v-if="show" class="p-4 bg-red-200 rounded shadow">元素 3: @after-enter</div>
</transition>
</div>
</template>
<style scoped>
</style>
@before-leave="onBeforeLeave"
(離場前):
@leave="onLeave"
(離場中):
@after-leave="onAfterLeave"
(離場後):
@leave-cancelled="onLeaveCancelled"
(離場取消):
done()
的正確使用姿勢什麼是 done()
:
done()
是一個回調函數,由 Vue 提供給進場或離場動效鉤子(如 @enter
、@leave
等)使用。它的作用是通知 Vue 當前的過渡動效已經完成,可以繼續下一步操作。done()
的必要性:
done()
通常不需要手動調用。done()
,告訴 Vue 動效已完成,否則 Vue 會無限等待動效的完成,導致動效行為卡住或其他過渡鉤子不會被執行。使用 done()
的方式:
在鉤子中設置自定義動效效果,例如 @enter
中,當動效邏輯結束後,必須調用 done()
才能讓 Vue 繼續執行後續流程。
例如,在 @enter
動效中,當動效完成後再執行 done()
,如下:
const onEnter = (el: Element, done: () => void) => {
// 設定自定義動效,例如改變樣式或使用其他動效庫
console.log(" @enter 進場動效活動!");
// 模擬動效完成的延遲
setTimeout(() => {
done(); // 必須調用,否則 Vue 不會知道動效已完成
console.log("進場動效結束");
}, 1000); // 這裡的時間要與動效的實際時間對應
};
典型的 done()
誤區:
done()
:這是最常見的問題,會導致動效狀態卡住
。done()
:這會使動效未完成時就通知 Vue,導致動效被中斷或沒有正確顯示。鉤子的大秘密:Vue.js 的 Transition Hooks 讓網頁切換不只是動,還能加點小魔法!
過渡模式小撇步:用 mode="in-out"
、mode="out-in"
決定誰先來、誰後走,換頁更流暢!
閃白OUT!:換頁「閃白」不用怕!記得存下背景色,換頁時延續顏色,畫面超順超自然!
進場&離場鉤子組合技:鉤子們一出手,各種進場、離場動態效果立刻安排起來!
done()
是個關鍵任務:動效過程完了要記得叫 done()
,不然 Vue 會以為你還沒結束,動效會卡住哦!
避免NG小提醒:別忘了 done()
,也別亂叫它,不然動效會大亂套!
這篇分享能讓我們一步步玩轉動效,小技巧掌握後,未來動效會越來越順手,動起來輕鬆又俐落哦!🎨✨🚀