Vue 入門到實戰 五

5章 過渡與動畫

目錄

5.1 單元素/組件過渡

5.1.1 過渡class

5.1.2 CSS 過渡

5.1.3 CSS 動畫

5.1.4 同時使用過渡和動畫

5.1.5 JavaScript 鉤子方法

5.2 多元素/組件過渡

5.2.1 多元素過渡

5.2.2 多組件過渡

5.3 列表過渡

5.3.1 列表的普通過渡

5.3.2 列表的平滑過渡

5.3.3 列表的變換過渡

5.3.4 多維列表的過渡


5.1 單元素/組件過渡

Vue在插入、更新或者移除 DOM 時,提供多種不同方式的過渡效果(一個淡入淡出的效果)。在條件渲染(使用v-if)、條件展示(使用v-show)、動態組件、組件根節點等情形中,可以給任何元素和組件添加進入/離開過渡。Vue提供了內置的過渡封裝組件<transition>,該組件用于包裹要實現過渡效果的組件。具體語法如下:

<transition name = "過渡名稱">

? <!--要實現過渡效果的組件-->

</transition>

5.1.1 過渡class

總結起來就分為?進入?和?離開?動畫的?初始狀態、生效狀態、結束狀態,具體如下:

  • v-enter-from
    • 進入?動畫的?起始狀態
    • 在元素插入之前添加,在元素插入完成后的?下一幀移除
  • v-enter-active
    • 進入?動畫的?生效狀態,應用于整個進入動畫階段
    • 在元素被插入之前添加,在過渡或動畫完成之后移除
    • 這個?class?可以被用來定義進入動畫的持續時間、延遲與速度曲線類型
  • v-enter-to
    • 進入?動畫的?結束狀態
    • 在元素插入完成后的下一幀被添加 (也就是?v-enter-from?被移除的同時),在過渡或動畫完成之后移除
  • v-leave-from
    • 離開?動畫的?起始狀態
    • 在離開過渡效果被觸發時立即添加,在一幀后被移除
  • v-leave-active
    • 離開?動畫的?生效狀態,應用于整個離開動畫階段
    • 在離開過渡效果被觸發時立即添加,在?過渡或動畫完成之后移除
    • 這個?class?可以被用來定義離開動畫的持續時間、延遲與速度曲線類型
  • v-leave-to
    • 離開?動畫的?結束狀態
    • 在一個離開動畫被觸發后的?下一幀?被添加 (即?v-leave-from?被移除的同時),在?過渡或動畫完成之后移除

其中的?v?前綴是允許修改的,可以?<Transition>?組件傳一個?name?的?prop?來聲明一個過渡效果名,如下就是將?v?前綴修改為?modal?前綴:

<div id="app"><button @click="show = !show">點我,我就漸漸的離開、漸漸的來。</button><transition name="fade"><p v-show="show" :style="styleobj">動畫實例</p></transition>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {show: true,styleobj: {fontSize: '30px',color: 'red'}}}})app.mount('#app')
</script>
<style>.fade-enter-active,.fade-leave-active {transition: opacity 2s ease;}.fade-enter-from,.fade-leave-to {opacity: 0;}
</style>

5.1.2 CSS 過渡

常用的過渡一般都是CSS過渡。CSS過渡,顧名思義也就是使用過渡class定義CSS實現過渡效果。

5-2】使用過渡class定義圖片的進入和離開動畫效果,運行效果如圖5.2所示。

?

<div id="app"><button @click="show = !show">切換顯示圖片</button><transition name="slide-img"><p v-if="show"><img src="99.jpg"/></p></transition>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {show: true}}})app.mount('#app')
</script>
<style>.slide-img-enter-active {	    transition: all 5s ease-out; //ease-out 規定以慢速結束的過渡,進入界面需要延遲5秒才會顯示整個圖片}.slide-img-leave-active {transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);}.slide-img-enter-from,.slide-img-leave-to {  transform: rotateX(45deg);   //X軸45°旋轉transform: rotateY(45deg);  transform: rotateZ(45deg);  transform: rotate3d(1, 1, 1, 45deg);opacity: 0;}
</style>

5.1.3 CSS 動畫

CSS動畫與CSS過渡用法相同,區別是在動畫中v-enter類名在節點插入DOM后不會立即被刪除,而是在animationend(動畫結束)事件觸發時刪除。

1. 基本概念
CSS 動畫由兩個主要部分組成:

@keyframes:定義動畫的關鍵幀,指定動畫在不同時間點的狀態。
? ? ?animation:應用于元素的屬性,控制動畫的播放、持續時間、延遲等。
2. @keyframes 關鍵幀的定義
@keyframes 定義了動畫的各個關鍵幀,控制元素的從一個狀態到另一個狀態的轉換過程。

5-3】使用@keyframes定義圖片的動畫規則,運行效果如圖5.3所示。

<div id="app"><button @click="show = !show">切換圖片動畫</button><transition name="bounce-img"><p v-if="show"><img src="99.jpg" /></p></transition>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {show: true}}})app.mount('#app')
</script>
<style>.bounce-img-enter-active {animation: bounce-in 0.8s;}.bounce-img-leave-active {animation: bounce-in 0.8s reverse;}@keyframes bounce-in {0% {transform: scale(0);}50% {transform: scale(1.25);}100% {transform: scale(1);}}
</style>

?

5.1.4 同時使用過渡和動畫

在一些應用場景中,需要給一個元素同時設置過渡和動畫,比如 animation 很快的被觸發并完成,而 transition 效果還沒結束。這時,需要使用 type屬性并設置 animation transition值來明確聲明需要Vue監聽的類型。

<transition> 組件的 duration prop上可顯性定義過渡持續時間(以毫秒計),比如,定制進入和移出的持續時間:<transition :duration="{ enter:1000, leave: 2000 }">...</transition>。還可以通過appear屬性設置DOM節點在初始渲染的過渡(頁面加載的初次過渡動畫):<transition appear>...</transition>

<head><!--使用第三方動畫庫--><link rel="stylesheet" type="text/css" href="https://cdn.bootcss.com/animate.css/3.7.2/animate.min.css">
</head>
<!--使用type='transition'以transition過渡時長為準,
即fade-enter-active和fade-leave-active定義的時長,
或者綁定屬性:duration="{enter:5000,leave:5000}"自定義時長,
type='transition'與:duration="5000" 二選一;
使用animate.css必須使用vue的 enter-active-class 和 leave-active-class,
后面緊跟animated類名和想使用的動畫名稱;
appear,appear-active-class實現頁面加載的初次動畫(初始渲染過渡)。-->
<div id="app"><transition name='fade' appear :duration="{enter:5000,leave:5000}"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><button @click="handleClick">切換顯示</button>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {show: true}},methods: {handleClick() {this.show = !this.show}}})app.mount('#app')
</script>
<style type="text/css">.fade-enter,.fade-leave-to {opacity: 0;}.fade-enter-active,.fade-leave-active {transition: opacity 5s;}div {font-size: 40px;margin: 50px auto;}
</style>

5.1.5 JavaScript 鉤子方法

?

<div id="app"><button @click="show = !show" class="btn">添加到購物車</button><transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter"><div v-if="show" class="ball"></div></transition>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {show: false}},methods: {//el表示將要執行動畫的DOM元素,beforeEnter表示動畫開始前beforeEnter(el) {//設置元素動畫開始前的起始位置el.style.transform = "translate(0, 0)"},enter(el, done) {//返回元素的寬度,強制動畫刷新el.offsetWidth//設置元素動畫開始之后的樣式,設置完成之后狀態el.style.transform = "translate(200px, -200px)"el.style.transition = "all 3s cubic-bezier(0, 0.54, 0.55, 1.18)"//done這里代表afterEnter方法的引用done()},afterEnter(el) {//動畫完成后,調用該方法this.show = !this.show}}})app.mount('#app')
</script>
<style>.ball {width: 30px;height: 30px;border-radius: 50%;background-color: green;position: absolute;z-index: 99;top: 200px;left: 100px;}.btn {position: absolute;top: 200px;}
</style>

5.2 多元素/組件過渡

5.2.1 多元素過渡

對于原生元素可以使用v-if/v-else實現多元素過渡。最常見的多元素過渡是一個列表和描述這個列表為空消息的元素:

<transition>

? <table v-if="items.length > 0">

? <!-- ... -->

? </table>

? <p v-else>沒有列表內容</p>

</transition>

實際上,通過使用多個v-if或將單個元素綁定到一個動態屬性上,可以在任意數量的元素之間進行過渡。

<div id="app"><button @click="handleClick('saved')">顯示Edit</button>&nbsp;&nbsp;<button @click="handleClick('edited')">顯示Save</button>&nbsp;&nbsp;<button @click="handleClick('editing')">顯示Cancel</button><br><br><transition name="fade" mode="out-in"><!--這里使用key讓vue區分相同標簽名元素,觸發過渡--><button :key="docState">{{ buttonMessage }}</button></transition>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {docState: ''}},methods: {handleClick(myVal) {this.docState = myVal}},computed: {buttonMessage() {switch (this.docState) {case 'saved': return 'Edit'case 'edited': return 'Save'case 'editing': return 'Cancel'default: return '初始按鈕'}}}})app.mount('#app')
</script>
<style type="text/css">.fade-enter-from,.fade-leave-to {opacity: 0;}.fade-enter-active,.fade-leave-active {transition: opacity 5s ease;}
</style>

5.2.2 多組件過渡

可以使用多組件過渡將多個組件包裝成動態組件的效果。

5-7】設計一個類似于選項卡的頁面,單擊“多組件過渡按鈕”將 “登錄子組件”和“注冊子組件”進行切換。

<div id="app"><button @click="show">多組件過渡按鈕</button><transition name="check" mode="out-in"><!-- is用來展示的template組件,mode組件切換的模式,name過渡的前綴,component占位符表示展示的組件 --><component :is="view"></component></transition>
</div>
<!-- 登錄子組件 -->
<template id="login"><div><h1>登錄子組件</h1></div>
</template>
<!-- 注冊子組件 -->
<template id="register"><div><h1>注冊子組件</h1></div>
</template>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {view: 'login'}},methods: {show: function () {if (this.view == "login") {this.view = "register"} else {this.view = "login"}}},components: {login: {template: "#login"},register: {template: "#register"}}})app.mount('#app')
</script>
<style type="text/css">.check-enter-from,.check-leave-to {opacity: 0;}.check-enter-active,.check-leave-active {transition: opacity 5s ease;}
</style>

5.3 列表過渡

對于列表元素,可使用<transition-group>組件進行過渡。<transition-group>組件具有以下幾個特點:

1、不同于 <transition>組件,它默認以<span>元素渲染。

2、過渡模式不可用,因為不再相互切換特有的元素。

3、內部元素需要提供唯一的key屬性值。

4CSS過渡類將會應用在組件內部的元素中,而不是組件本身。

5.3.1 列表的普通過渡

5.3.2 列表的平滑過渡

在例5-8中,當添加和移除元素時,周圍元素將瞬間移動到它們的新布局位置,而不是平滑的過渡。

<transition-group> 組件不僅可以進入和離開列表過渡,還可以通過v-move特性改變定位,進行平滑過渡。v-move特性像之前的類名一樣,可以通過name屬性來自定義前綴。

<div id="list-demo" class="demo"><button @click="add">添加元素</button>&nbsp;<button @click="remove">移除元素</button><transition-group name="list" tag="p"><span v-for="item in items" :key="item" class="list-item">{{item}}</span></transition-group>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {items: [1, 2, 3, 4, 5, 6, 7, 8, 9],nextNum: 10}},methods: {randomIndex() {return Math.floor(Math.random() * this.items.length)},add() {this.items.splice(this.randomIndex(), 0, this.nextNum++)},remove() {this.items.splice(this.randomIndex(), 1)}}})app.mount('#list-demo')
</script>
<style>.list-item {display: inline-block;margin-right: 10px;}.list-enter-active,.list-leave-active {transition: all 3s;}.list-enter,.list-leave-to {opacity: 0;transform: translateY(30px);}
</style>

5-9】列表的平滑過渡,可以在例5-8的基礎上,做出如下改進:1、增加.list-move樣式,使元素在進入時實現過渡效果;2、在.list-leave-active中設置絕對定位,使元素在離開時實現過渡效果。

<div id="list-demo" class="demo"><button @click="add">添加元素</button>&nbsp;<button @click="remove">移除元素</button><transition-group name="list" tag="p"><span v-for="item in items" :key="item" class="list-item">{{item}}</span></transition-group>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {items: [1, 2, 3, 4, 5, 6, 7, 8, 9],nextNum: 10}},methods: {randomIndex() {return Math.floor(Math.random() * this.items.length)},add() {this.items.splice(this.randomIndex(), 0, this.nextNum++)},remove() {this.items.splice(this.randomIndex(), 1)}}})app.mount('#list-demo')
</script>
<style>.list-item {display: inline-block;margin-right: 10px;}.list-move,.list-enter-active,.list-leave-active {transition: 3s;}.list-leave-active {position: absolute;}.list-enter,.list-leave-to {opacity: 0;transform: translateY(30px);}
</style>

5.3.3 列表的變換過渡

利用move屬性,進行變換過渡,即一個列表中的列表項既不增加也不減少,只是不斷地變換其位置。

5-10】列表的變換過渡。

<div id="list-demo" class="demo"><button @click="shuffle">變換過渡</button><transition-group name="list" tag="ul"><li v-for="item in items" :key="item">{{item}}</li></transition-group>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {items: [1, 2, 3, 4, 5, 6, 7, 8, 9],nextNum: 10}},methods: {shuffle() {this.items = this.items.sort(() => { return Math.random() - 0.5; })}}})app.mount('#list-demo')
</script>
<style>.list-move {transition: transform 3s;}
</style>

5.3.4 多維列表的過渡

FLIP動畫不僅可以實現單列表過渡,多維網格列表的過渡也同樣簡單。

5-11】多維網格列表的過渡。

<div id="list-demo" class="demo"><button @click="shuffle">多維列表變換</button><transition-group name="cell" tag="div" class="container"><span v-for="cell in cells" :key="cell.id" class="cell">{{ cell.number }}</span></transition-group>
</div>
<script src="js/vue.global.js"></script>
<script>const app = Vue.createApp({data() {return {cells: Array.apply(null, { length: 81 }).map(function (_, index) {return {id: index,number: index % 9 + 1}})}},methods: {shuffle() {this.cells = this.cells.sort(() => { return Math.random() - 0.5; })}}})app.mount('#list-demo')
</script>
<style>.container {width: 270px;margin-top: 10px;line-height: 30px;text-align: center;}.cell {display: inline-block;width: 30px;height: 30px;outline: 1px solid #aaa;}.cell-move {transition: 3s;}
</style>

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/74221.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74221.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/74221.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Apache SeaTunnel腳本升級及參數調優實戰

最近作者針對實時數倉的Apache SeaTunnel同步鏈路&#xff0c;完成了雙引擎架構升級與全鏈路參數深度調優&#xff0c;希望本文能夠給大家有所啟發&#xff0c;歡迎批評指正&#xff01; Apache SeaTunnel 版本 &#xff1a;2.3.9 Doris版本&#xff1a;2.0.6 MySQL JDBC Conne…

C++ 時間操作:獲取有史以來的天數與文件計數器

C 時間操作&#xff1a;獲取有史以來的天數與文件計數器 在C中&#xff0c;時間操作是一個非常重要的功能&#xff0c;尤其是在需要處理日期、時間戳或定時任務時。本文將介紹如何利用C的時間操作功能&#xff0c;實現以下兩個目標&#xff1a; 獲取從Unix紀元時間&#xff0…

Python Bug修復案例分析:Python 中常見的 IndentationError 錯誤 bug 的修復

在 Python 編程的世界里&#xff0c;代碼的可讀性和規范性至關重要。Python 通過強制使用縮進來表示代碼塊的層次結構&#xff0c;這一獨特的設計理念使得代碼更加清晰易讀。然而&#xff0c;正是這種對縮進的嚴格要求&#xff0c;導致開發者在編寫代碼時&#xff0c;稍有不慎就…

【論文筆記】Transformer

Transformer 2017 年&#xff0c;谷歌團隊提出 Transformer 結構&#xff0c;Transformer 首先應用在自然語言處理領域中的機器翻譯任務上&#xff0c;Transformer 結構完全構建于注意力機制&#xff0c;完全丟棄遞歸和卷積的結構&#xff0c;這使得 Transformer 結構效率更高…

CI/CD(三) 安裝nfs并指定k8s默認storageClass

一、NFS 服務端安裝&#xff08;主節點 10.60.0.20&#xff09; 1. 安裝 NFS 服務端 sudo apt update sudo apt install -y nfs-kernel-server 2. 創建共享目錄并配置權限 sudo mkdir -p /data/k8s sudo chown nobody:nogroup /data/k8s # 允許匿名訪問 sudo chmod 777 /dat…

【QA】單件模式在Qt中有哪些應用?

單例設計模式確保一個類僅有一個實例&#xff0c;并提供一個全局訪問點來獲取該實例。在 Qt 框架中&#xff0c;有不少類的設計采用了單例模式&#xff0c;以下為你詳細介紹并給出相應代碼示例。 1. QApplication QApplication 是 Qt GUI 應用程序的核心類&#xff0c;每個 Q…

存儲過程觸發器習題整理1

46、{blank}設有商品表(商品號&#xff0c;商品名&#xff0c;單價)和銷售表(銷售單據號&#xff0c;商品號&#xff0c;銷售時間&#xff0c;銷售數量&#xff0c;銷售單價)。其中&#xff0c;商品號代表一類商品&#xff0c;商品號、單價、銷售數量和銷售單價均為整型。請編寫…

基于ChatGPT、GIS與Python機器學習的地質災害風險評估、易發性分析、信息化建庫及災后重建高級實踐

第一章、ChatGPT、DeepSeek大語言模型提示詞與地質災害基礎及平臺介紹【基礎實踐篇】 1、什么是大模型&#xff1f; 大模型&#xff08;Large Language Model, LLM&#xff09;是一種基于深度學習技術的大規模自然語言處理模型。 代表性大模型&#xff1a;GPT-4、BERT、T5、Ch…

單表達式倒計時工具:datetime的極度優雅(智普清言)

一個簡單表達式&#xff0c;也可以優雅自成工具。 筆記模板由python腳本于2025-03-22 20:25:49創建&#xff0c;本篇筆記適合任意喜歡學習的coder翻閱。 【學習的細節是歡悅的歷程】 博客的核心價值&#xff1a;在于輸出思考與經驗&#xff0c;而不僅僅是知識的簡單復述。 Pyth…

最優編碼樹的雙子性

現在看一些書&#xff0c;不太愿意在書上面做一些標記&#xff0c;也沒啥特殊的原因。。哈哈。 樹的定義 無環連通圖&#xff0c;極小連通圖&#xff0c;極大無環圖。 度 某個節點&#xff0c;描述它的度&#xff0c;一般默認是出度&#xff0c;分叉的邊的條數。或者說孩子…

MiB和MB

本文來自騰訊元寶 MiB 和 ?MB 有區別&#xff0c;盡管它們都用于表示數據存儲的單位&#xff0c;但它們的計算方式不同&#xff0c;分別基于不同的進制系統。 1. ?MiB&#xff08;Mebibyte&#xff09;? ?MiB 是基于二進制的單位&#xff0c;使用1024作為基數。1 MiB 102…

Labview和C#調用KNX API 相關東西

敘述:完全沒有聽說過KNX這個協議...................我這次項目中也是簡單的用了一下沒有過多的去研究 C#調用示例工程鏈接(labview調用示例在 DEBUG文件夾里面) 通過網盤分享的文件&#xff1a;KNX調用示例.zip 鏈接: https://pan.baidu.com/s/1NQUEYM11HID0M4ksetrTyg?pwd…

損失函數理解(二)——交叉熵損失

損失函數的目的是為了定量描述不同模型&#xff08;例如神經網絡模型和人腦模型&#xff09;的差異。 交叉熵&#xff0c;顧名思義&#xff0c;與熵有關&#xff0c;先把模型換成熵這么一個數值&#xff0c;然后用這個數值比較不同模型之間的差異。 為什么要做這一步轉換&…

Kubernetes的Replica Set和ReplicaController有什么區別

ReplicaSet 和 ReplicationController 是 Kubernetes 中用于管理應用程序副本的兩種資源&#xff0c;它們有類似的功能&#xff0c;但 ReplicaSet 是 ReplicationController 的增強版本。 以下是它們的主要區別&#xff1a; 1. 功能的演進 ReplicationController 是 Kubernete…

信息系統運行管理員教程3--信息系統設施運維

第3章 信息系統設施運維 信息系統設施是支撐信息系統業務活動的信息系統軟硬件資產及環境。 第1節 信息系統設施運維的管理體系 信息系統設施運維的范圍包含信息系統涉及的所有設備及環境&#xff0c;主要包括基礎環境、硬件設備、網絡設備、基礎軟件等。 信息系統設施運維…

如何通過Python實現自動化任務:從入門到實踐

在當今快節奏的數字化時代,自動化技術正逐漸成為提高工作效率的利器。無論是處理重復性任務,還是管理復雜的工作流程,自動化都能為我們節省大量時間和精力。本文將以Python為例,帶你從零開始學習如何實現自動化任務,并通過一個實際案例展示其強大功能。 一、為什么選擇Pyt…

Spring Boot 與 MyBatis Plus 整合 KWDB 實現 JDBC 數據訪問

? 引言 本文主要介紹如何在 IDEA 中搭建一個使用 Maven 管理的 Spring Boot 應用項目工程&#xff0c;并結合在本地搭建的 KWDB 數據庫&#xff08;版本為&#xff1a;2.0.3&#xff09;來演示 Spring Boot 與 MyBatis Plus 的集成&#xff0c;以及對 KWDB 數據庫的數據操作…

Java鎖等待喚醒機制

在 Java 并發編程中&#xff0c;鎖的等待和喚醒機制至關重要&#xff0c;通常使用 wait()、notify() 和 notifyAll() 來實現線程間的協調。本文將詳細介紹這些方法的用法&#xff0c;并通過示例代碼加以說明。 1. wait()、notify() 與 notifyAll() 在 Java 中&#xff0c;Obj…

? UNIX網絡編程筆記:TCP客戶/服務器程序示例

服務器實例 有個著名的項目&#xff0c;tiny web&#xff0c;本項目將其改到windows下&#xff0c;并使用RAII重構&#xff0c;編寫過程中對于內存泄漏確實很頭疼&#xff0c;還沒寫完&#xff0c;后面會繼續更&#xff1a; #include <iostream> #include <vector&g…

AI Agent開發大全第四課-提示語工程:從簡單命令到AI對話的“魔法”公式

什么是提示語工程&#xff1f;一個讓AI“聽話”的秘密 如果你曾經嘗試過用ChatGPT或者其他大語言模型完成任務&#xff0c;那么你一定遇到過這樣的情況&#xff1a;明明你的問題是清晰的&#xff0c;但答案卻離題萬里&#xff1b;或者你認為自己提供的信息足夠詳盡&#xff0c…