<template>
<div>
<button @click="isShow=!isShow">切換顯示
<transition name="fade">
<p v-if="isShow">隱藏訊息</p>
</transition>
</div>
</template>
<script setup>
import {ref} from 'vue'
const isShow = ref(false);
</script>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: opacity 2s;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
圖1:使用Vue.js原生動畫功能transition搭配v-if
由以上範例可以看出,雖然Vue.js精簡化了動畫效果的設計,但是還是必須要針對此動畫設計一組特定的CSS Class來做搭配,在開發上還是帶來了一些負擔。
有鑑於此,筆者向各位介紹一個方便好用又輕量化的動畫元件-AutoAnimate。(https://auto-animate.formkit.com/)
AutoAnimate 的核心理念在於提供一個「零設定」的動畫元件,它的目的是簡化在網頁應用中設計動畫效果的過程,讓開發者不用編寫複雜的 CSS 或 JavaScript 。只需將這個元件引入到Vue.js的專案中,就能輕鬆為網頁元素增加動畫效果,進而提升使用者操作體驗。
AutoAnimate的特色
- 簡單易用:
AutoAnimate 只需一行語法即可啟動動畫。開發者只需要將語法撰寫至指定的 HTML 元素或其父容器,該元件會自動處理新增、刪除或變動元素時的動畫效果。 - 跨框架支援:
AutoAnimate 支援多種前端框架,包括 Vue、React、Svelte與Solid 等。它以非常輕量的方式運作,因此無論是在小型應用還是大型項目中,都不會增加太多額外負擔。 - 自動偵測 DOM 變更:
AutoAnimate 能夠自動偵測 DOM 元素中的變更,無需手動設置或追蹤變化。無論是新增Html元素、刪除Html元素,還是Html元素位置發生改變,工具都會自動在這些變化中添加平滑的動畫效果。 - 無需額外配置:
大多數動畫工具需要設定時間線、關鍵幀或過渡參數,而 AutoAnimate 完全跳過了這些繁瑣的步驟,預設提供流暢且符合常見需求的動畫效果。
以下介紹AutoAnimate的安裝方式:
安裝AutoAnimate
使用AutoAnimate的第一步,就是使用npm工具輸入以下指令,安裝元件至Vue.js的專案之中:
npm install @formkit/auto-animate
註冊AutoAnimate
接著至main.js內,將AutoAnimate註冊至全域範圍,那之後其他的Component就可以直接使用了,main.js的程式碼如下:
import { createApp } from 'vue'
import App from './App.vue'
import { autoAnimatePlugin } from
'@formkit/auto-animate/vue'
createApp(App).use(autoAnimatePlugin).mount('#app')
以下為幾個以組合式API為主設計範例:
範例1:移除清單成員
以下為未設置AutoAnimate的Component完整內容
<template>
<h5>點選以下文字可移除</h5>
<ul>
<li v-for="item in items" :key="item"
@click="removeItem(item)">
{{ item }}
</li>
</ul>
</template>
<script setup>
import { ref } from 'vue'
const items = ref(["台北", "台中", "高雄", "新竹", "台南"])
function removeItem(toRemove) {
items.value = items.value.filter((item) => item !== toRemove)
}
</script>
<style scoped></style>
可參考下圖,刪除成員時,並無動畫效果:
圖2:移除成員(無動畫效果)
接著,只要在父容器標籤<ul>中,加入AutoAnimate所提供的指示詞(Directive) v-auto-animate,就可以增加刪除成員時的動畫效果,加入後的標籤如下:
<ul v-auto-animate>
<li v-for="item in items" :key="item" @click="removeItem(item)">
{{ item }}
</li>
</ul>
接著再次執行,即可得到動畫效果,如下圖所示:
圖3:移除成員(加入動畫效果)
範例2:排序清單成員與動態關閉動畫效果
以下為Component的完整內容:
<template>
<div>
<button @click="sortAsc">正排序 ↑</button>
<button @click="sortDesc">反排序 ↓</button>
<button @click="toggleEnable">切換動畫效果 ({{isEnable}})</button>
</div>
<ul ref="parent">
<li v-for="item in items" :key="item">
{{ item }}
</li>
</ul>
</template>
<script setup>
import { ref } from 'vue'
import { useAutoAnimate } from '@formkit/auto-animate/vue'
const [parent , enable] = useAutoAnimate()
const items = ref([30, 20, 10, 40])
const isEnable = ref(true);
function toggleEnable(){
isEnable.value = !isEnable.value;
enable(isEnable.value);
}
function sortAsc() {
items.value.sort()
}
function sortDesc() {
items.value.sort().reverse()
}
</script>
<style scoped></style>
這個範例中定義了3個按鈕:
- 正排序按鈕:點擊後會觸發 sortAsc methods,對列表進行升冪排序。
- 反排序按鈕:點擊後會觸發 sortDesc methods,對列表進行降冪排序。
- 切換動畫按鈕:點擊後會切換是否啟用動畫效果,並顯示當前動畫是否啟用。
程式說明:
- useAutoAnimate():
使用import關鍵字匯入來自 @formkit/auto-animate/vue的useAutoAnimate function。 - Parent:
藉由呼叫useAutoAnimate()得回的第一個參數,搭配模板參考的語法提供給父容器標籤使用即可得到動畫效果。 - enable:
藉由呼叫useAutoAnimate()得回的第二個參數,控制動畫啟用/停用的函數, 使用enable(false)即可將動畫效果關閉。
執行此範例後,將會呈現以下效果:當頁面開啟後,您可以點擊「正排序」或「反排序」按鈕,隨後下方的序列成員將以動畫形式重新排列,如圖4所示:
圖4:排列清單成員(有動畫效果)
接著,點選了「切換動畫效果(true)」的按鈕,即可將動畫效果關閉,此時點擊「正排序」或「反排序」按鈕,隨後下方的序列成員重新排列則無動畫效果,如圖5所示
圖5:排列清單成員(有動畫效果)
範例3:增加清單成員與顯示隱藏標籤的動畫效果
以下為Component完整內容:
<script setup>
import { ref } from "vue"
const faq = ref([
{
id: "why_tokyo",
question: "為什麼要去東京?",
answer: `東京是一個充滿活力的城市,融合了傳統與現代文化。
從古老的神社到時尚的購物區,還有世界知名的美食與科技,
這裡提供多樣化的體驗,讓每個訪客都能找到自己喜歡的活動。`,
},
{
id: "why_london",
question: "為什麼要去倫敦?",
answer: `倫敦是歷史與現代交融的完美範例。著名的地標如大笨鐘、
倫敦塔和白金漢宮,使這座城市充滿了歷史意義。同時,
倫敦也以其博物館、劇院和國際美食而聞名,提供豐富的文化體驗。`,
},
{
id: "why_rome",
question: "為什麼要去羅馬?",
answer: `羅馬是古代文明的中心,擁有無數的歷史遺跡,
如羅馬競技場和萬神殿。漫步在這座城市中,您會感受到千年歷史的痕跡。
同時,羅馬也是義大利美食的故鄉,為美食愛好者提供了無數的驚喜。`,
}
])
const current = ref(faq.value[0].id)
function addNew(card) {
faq.value.unshift({
id: "why_taipei",
question: "為什麼要去台北?",
answer: `台北是一座融合傳統與現代的城市,擁有豐富的文化景點
和迷人的自然風光。您可以參觀壯麗的台北101,或探索故宮博物院
的珍貴文物。夜市的小吃更是讓美食愛好者大快朵頤,
展現了台灣多元的飲食文化。`,
})
}
</script>
<template>
<div class="example accordion-example">
<button @click="addNew">增加一個新景點</button>
<ul class="accordion" v-auto-animate>
<li class="accordion-item" v-for="q in faq" :key="q.id" v-auto-animate>
<div class="question" @click="current = current === q.id ? false : q.id">
{{ q.question }}
</div>
<p class="answer" v-if="q.id === current" v-html="q.answer" />
</li>
</ul>
</div>
</template>
<style scoped>
ul {
list-style-type: none;
margin: 0;
padding: 0;
}
li {
display: block;
background-color: var(--ui-light);
border-radius: 0.5em;
overflow: hidden;
}
[data-dark-mode="true"] li {
background-color: var(--purple-d);
}
.question {
padding: 1em;
display: flex;
align-items: center;
cursor: pointer;
}
.question::before {
content: "Q";
font-size: 1.5em;
margin-right: 0.5em;
color: var(--primary);
}
[data-dark-mode="true"] .question::before {
color: var(--purple-m);
}
.answer {
margin: 0 1rem;
padding: 0 0 1rem 0;
font-size: 0.875em;
}
</style>
這個範例中定義了2個點擊功能:
- 「<button @click="addNew">增加一個新景點</button>」標籤: 點擊後會觸發 addNew methods,在 FAQ 列表的最前面動態新增一個景點的問題與答案。
- 「<div class="question" …>」 標籤: 用來切換下方<p class="answer"…>標籤的顯示與隱藏
而上方的兩個點擊功能,如果都希望操作時能夠具有動畫效果,就必須要在各自的的父容器標籤加入[v-auto-animate]指示詞,此兩個父節點標籤分別為:
- <ul class="accordion" v-auto-animate>
- <li class="accordion-item" ...>
執行此範例後,將會呈現以下效果:當頁面開啟後,您可以點擊「為什麼要去東京?」、「為什麼要去倫敦?」或「為什麼要去羅馬?」按鈕,隨後該問題的下方將以動畫形式呈現出答案,如圖6所示:
圖6:使用動畫效果呈現各景點的答案
接著,點選了「增加一個新景點」的按鈕,就會看到清單內會使用動畫效果增加一個「為什麼要去台北?」的成員,並且在點選「為什麼要去台北?」的標題之後,隨後該問題的下方將也會動畫形式呈現出答案,如圖7所示:
圖7:使用動畫效果增加清單成員
結論:
AutoAnimate 是一個強大且易於使用的工具,它的「零設定」特性使其非常適合於開發過程中設計出動畫效果進而增進使用者的操作體驗。無論是在簡單的SPA 應用程式或是更複雜的動態系統中,AutoAnimate 都能輕鬆加入動畫,並讓清單異動時的視覺效果更為流暢自然,如有興趣可參考官網:https://auto-animate.formkit.com/