Vue中實(shí)現(xiàn)過渡動畫效果示例代碼
Vue的transition動畫
Transition動畫的使用
在開發(fā)中,我們想要給一個(gè)組件的顯示和消失添加某種過渡動畫,可以很好的增加用戶體驗(yàn):
React框架本身并沒有提供任何動畫相關(guān)的API,所以在React中使用過渡動畫我們需要使用一個(gè)第三方庫 react-transition-group;
Vue中為我們提供一些內(nèi)置組件和對應(yīng)的API來完成動畫,利用它們我們可以方便的實(shí)現(xiàn)過渡動畫效果;
我們來看一個(gè)案例:
Hello World的顯示和隱藏;
通過下面的代碼實(shí)現(xiàn),顯式和隱藏Hello World是不會有任何動畫效果的;
<template> <div class="app"> <button @click="btnClick">Toogle</button> <h2 v-show="isShow">Hello World</h2> </div> </template> <script setup> import { ref } from 'vue'; const isShow = ref(true) const btnClick = () => { isShow.value = !isShow.value } </script>
沒有動畫的情況下,整個(gè)內(nèi)容的顯示和隱藏會非常的生硬:
如果我們希望給單元素或者組件實(shí)現(xiàn)過渡動畫,可以使用Vue提供的 transition 內(nèi)置組件來完成動畫;
Vue 提供了 transition 的封裝組件,在下列情形中,可以給任何元素和組件添加進(jìn)入/離開過渡:
條件渲染 (使用 v-if)條件展示 (使用 v-show)
動態(tài)組件
組件根節(jié)點(diǎn)
例如我們給剛剛的Hello World添加動畫, 首先定義類(類的名字暫時(shí)是固定的)
/* 從什么狀態(tài)進(jìn)入 */ .v-enter-from { opacity: 0; } /* 進(jìn)入之后打算變成的狀態(tài) */ .v-enter-to { opacity: 1; } /* 進(jìn)入的過程中做什么 */ .v-enter-active { transition: opacity 2s linear; }
定義好類之后, 我們可以使用Vue的內(nèi)置組件 transition 將動畫元素包裹起來, transition 組件會自動在合適的時(shí)機(jī), 將合適的類添加到它所包裹的元素上
<template> <div class="app"> <button @click="btnClick">Toogle</button> <!-- 使用內(nèi)置組件包裹h2 --> <transition> <h2 v-show="isShow">Hello World</h2> </transition> </div> </template>
此時(shí)顯式Hello World 就已經(jīng)有動畫效果了, 但是隱藏時(shí)并沒有效果, 是因?yàn)槲覀儎倓偠x的類是進(jìn)入的類, 當(dāng)離開時(shí)我們也應(yīng)該定義對應(yīng)的類
/* 離開后的狀態(tài) */ .v-leave-to, /* 從什么狀態(tài)進(jìn)入 */ .v-enter-from { opacity: 0; } /* 開始離開的狀態(tài) */ .v-leave-from, /* 進(jìn)入之后打算變成的狀態(tài) */ .v-enter-to { opacity: 1; } /* 離開過程中做什么 */ .v-leave-active, /* 進(jìn)入的過程中做什么 */ .v-enter-active { transition: opacity 1s linear; }
Transition組件的原理
我們會發(fā)現(xiàn),上面演示代碼中Vue自動給h2元素添加了動畫,這是什么原因呢?
當(dāng)插入或刪除包含在 transition 組件中的元素時(shí), Vue 將會做以下處理:
1.自動嗅探目標(biāo)元素是否應(yīng)用了CSS過渡或者動畫,如果有,那么在恰當(dāng)?shù)臅r(shí)機(jī)添加/刪除 CSS類名;
2.如果 transition 組件提供了JavaScript鉤子函數(shù),這些鉤子函數(shù)將在恰當(dāng)?shù)臅r(shí)機(jī)被調(diào)用;
3.如果沒有找到JavaScript鉤子并且也沒有檢測到CSS過渡/動畫, DOM插入、刪除操作將會立即執(zhí)行;
在上面我們簡單使用了Vue會自動添加/刪除的CSS類名, 接下來我們詳細(xì)學(xué)習(xí)一下都有哪些類吧
Transition動畫的class
我們會發(fā)現(xiàn)上面提到了很多個(gè)class,事實(shí)上Vue就是幫助我們在這些class之間來回切換完成的動畫:
v-enter-from
:定義進(jìn)入過渡的開始狀態(tài)。
在元素被插入之前生效,在元素被插入之后的下一幀移除。
v-enter-active
:定義進(jìn)入過渡生效時(shí)的狀態(tài)。
在整個(gè)進(jìn)入過渡的階段中應(yīng)用,在元素被插入之前生效,在過渡/動畫完成之后移除。這個(gè)類可以被用來定義進(jìn)入過渡的過程時(shí)間,延遲和曲線 函數(shù)。
v-enter-to
:定義進(jìn)入過渡的結(jié)束狀態(tài)。
在元素被插入之后下一幀生效 (與此同時(shí) v-enter-from 被移除),在過渡/動畫完成之后移除。
v-leave-from
:定義離開過渡的開始狀態(tài)。
在離開過渡被觸發(fā)時(shí)立刻生效,下一幀被移除。
v-leave-active
:定義離開過渡生效時(shí)的狀態(tài)。
在整個(gè)離開過渡的階段中應(yīng)用,在離開過渡被觸發(fā)時(shí)立刻生效,在過渡/動畫完成之后移除。這個(gè)類可以被用來定義離開過渡的過程時(shí)間,延遲 和曲線函數(shù)。
v-leave-to
:離開過渡的結(jié)束狀態(tài)。
在離開過渡被觸發(fā)之后下一幀生效 (與此同時(shí) v-leave-from 被刪除),在過渡/動畫完成之后移除。
class的name命名規(guī)則如下:
如果我們使用的是一個(gè)沒有name屬性的transition,那么所有的class是以 v- 作為默認(rèn)前綴;
如果我們添加了一個(gè)name屬性,比如<transtion name= “abc” >,那么所有的class會以 abc- 開頭;
Vue的animation動畫
Animation動畫的使用
例如有一段文本, 我們對文本的顯式隱藏添加上一些動畫
先定義類, 用于實(shí)現(xiàn)動畫
/* 定義進(jìn)入的動畫 */ .v-enter-active { animation: myAnim 2s linear; } /* 定義離開的動畫 */ .v-leave-active { animation: myAnim 2s linear reverse; } /* 定義序列幀動畫 */ @keyframes myAnim { 0% { transform: scale(0); opacity: 0; } 50% { transform: scale(1.25); opacity: 0.5; } 100% { transform: scale(1); opacity: 1; } }
同transition動畫, 使用transition組件包裹
<template> <div class="app"> <button @click="btnClick">Toogle</button> <!-- 使用內(nèi)置組件包裹h2 --> <transition> <h2 v-show="isShow"> 今天2022年8月6日星期六,利好消息來襲!因?yàn)榻?jīng)濟(jì)數(shù)據(jù)仍顯疲軟, 市場對全球經(jīng)濟(jì)增速放緩可能抑制需求的擔(dān)憂加劇,導(dǎo)致成品油調(diào)價(jià) 掛靠的國際油價(jià)繼續(xù)下挫,同時(shí)綜合原油品種變化率也已經(jīng)完成正值 到負(fù)值的轉(zhuǎn)變。數(shù)據(jù)顯示:截至國內(nèi)成品油調(diào)價(jià)周期的第8個(gè)工作日 結(jié)束,原油綜合變化率為-0.83%,詳細(xì)成品油調(diào)價(jià)窗口開啟時(shí)間定在 8月9日24時(shí)開啟。 </h2> </transition> </div> </template>
同時(shí)設(shè)置兩種動畫(了解)
Vue為了知道過渡的完成,內(nèi)部是在監(jiān)聽 transitionend 或 animationend,到底使用哪一個(gè)取決于元素應(yīng)用的CSS規(guī)則:
如果我們只是使用了其中的一個(gè),那么Vue能自動識別類型并設(shè)置監(jiān)聽;
但是如果我們同時(shí)使用了transition動畫和animation動畫呢?
在開發(fā)中, 如果設(shè)置了兩個(gè)動畫, 盡量要保持兩個(gè)動畫的時(shí)間一致;
/* 定義transition動畫 */ .v-enter-from, .v-leave-to { opacity: 0; } .v-enter-to, .v-leave-from { opacity: 1; } .v-enter-active { /* 設(shè)置兩個(gè)不同的動畫, 最好保持動畫時(shí)間一致 */ animation: myAnim 2s linear; transition: opacity 2s linear; } .v-leave-active { /* 設(shè)置兩個(gè)不同的動畫, 最好保持動畫時(shí)間一致 */ animation: myAnim 2s linear reverse; transition: opacity 2s linear; } /* 定義序列幀動畫 */ @keyframes myAnim { 0% { transform: scale(0); opacity: 0; } 50% { transform: scale(1.25); opacity: 0.5; } 100% { transform: scale(1); opacity: 1; } }
如果使用兩個(gè)動畫, 動畫的時(shí)間又不一致, 并且在這個(gè)情況下可能某一個(gè)動畫執(zhí)行結(jié)束時(shí),另外一個(gè)動畫還沒有結(jié)
在這種情況下,我們可以設(shè)置 type 屬性為 animation 或者 transition 來明確的告知Vue監(jiān)聽的類型, 以哪一個(gè)動畫為標(biāo)準(zhǔn)(一般不設(shè)置);
<!-- 告知以哪一個(gè)動畫為標(biāo)準(zhǔn) --> <transition type="transition"> <h2 v-show="isShow"> 今天2022年8月6日星期六,利好消息來襲!因?yàn)榻?jīng)濟(jì)數(shù)據(jù)仍顯疲軟, 市場對全球經(jīng)濟(jì)增速放緩可能抑制需求的擔(dān)憂加劇,導(dǎo)致成品油調(diào)價(jià) 掛靠的國際油價(jià)繼續(xù)下挫,同時(shí)綜合原油品種變化率也已經(jīng)完成正值 到負(fù)值的轉(zhuǎn)變。數(shù)據(jù)顯示:截至國內(nèi)成品油調(diào)價(jià)周期的第8個(gè)工作日 結(jié)束,原油綜合變化率為-0.83%,詳細(xì)成品油調(diào)價(jià)窗口開啟時(shí)間定在 8月9日24時(shí)開啟。 </h2> </transition>
過渡的模式mode
我們來看當(dāng)前的動畫在兩個(gè)元素之間顯式隱藏切換的時(shí)候添加動畫存在的問題:
我們會發(fā)現(xiàn) Hello World 和 你好啊,李銀河是同時(shí)存在的:
這是因?yàn)槟J(rèn)情況下進(jìn)入和離開動畫是同時(shí)發(fā)生的;
如果確實(shí)我們希望達(dá)到這個(gè)的效果,那么是沒有問題;
但是如果我們不希望同時(shí)執(zhí)行進(jìn)入和離開動畫,那么我們需要設(shè)置transition的過渡模式:
in-out: 新元素先進(jìn)行過渡,完成之后當(dāng)前元素過渡離開;
out-in: 當(dāng)前元素先進(jìn)行過渡,完成之后新元素過渡進(jìn)入;
<transition mode="in-out"> <h2>Hello Worl</h2> <h2>你好啊, 李銀河</h2> </transition>
上面的示例同樣適用于我們的動態(tài)組件:
<div class="app"> <div> <button @click="isShow = !isShow">切換</button> </div> <transition name="why" mode="out-in"> <component :is=" isShow ? 'home': 'about'"></component> </transition> </div>
默認(rèn)情況下,首次渲染的時(shí)候是沒有動畫的,如果我們希望給他添加上去動畫,那么就可以增加另外一個(gè)屬性appear:
<div class="app"> <div> <button @click="isShow = !isShow">切換</button> </div> <transition name="why" mode="out-in" appear=""> <component :is=" isShow ? 'home': 'about'"></component> </transition> </div>
列表過渡
列表過渡的介紹
目前為止,過渡動畫我們只要是針對單個(gè)元素或者組件的:
要么是單個(gè)節(jié)點(diǎn);
要么是同一時(shí)間渲染多個(gè)節(jié)點(diǎn)中的一個(gè);
那么如果希望渲染的是一個(gè)列表,并且該列表中添加刪除數(shù)據(jù)也希望有動畫執(zhí)行呢?
這個(gè)時(shí)候我們要使用<transition-group>組件來完成;
使用<transition-group>有如下的特點(diǎn):
默認(rèn)情況下,它不會渲染成任何一個(gè)元素,但是你可以指定一個(gè)元素并以 tag attribute 讓他進(jìn)行渲染;
過渡模式不可用,因?yàn)槲覀儾辉傧嗷デ袚Q特有的元素;
內(nèi)部元素總是需要提供唯一的 key attribute 值;
CSS 過渡的類將會應(yīng)用在內(nèi)部的元素中,而不是這個(gè)組/容器本身;
列表過渡的使用
我們來做一個(gè)案例:
案例是一列數(shù)字,可以繼續(xù)添加或者刪除數(shù)字;
在添加和刪除數(shù)字的過程中,對添加的或者移除的數(shù)字添加動畫;
示例代碼如下
<template> <div class="app"> <button @click="addNumber">添加數(shù)字</button> <button @click="removeNumber">刪除數(shù)字</button> <template v-for="item in nums" :key="item"> <span>{{ item }}</span> </template> </div> </template> <script setup> import { ref } from 'vue'; const nums = ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) const addNumber = () => { nums.value.splice(randomIndex(), 0, nums.value.length) } const removeNumber = () => { nums.value.splice(randomIndex(), 1) } const randomIndex = () => { return Math.floor(Math.random() * nums.value.length) } </script>
添加動畫, 此時(shí)添加上動畫, 這個(gè)組中的內(nèi)容都會有動畫效果
span { margin-right: 20px; display: inline-block; } .v-enter-from, .v-leave-to { opacity: 0; transform: translateY(20px); } .v-enter-to, .v-leave-from { opacity: 1; transform: translateY(0); } .v-enter-active, .v-leave-active { transition: all 2s linear; }
<template> <div class="app"> <button @click="addNumber">添加數(shù)字</button> <button @click="removeNumber">刪除數(shù)字</button> <!-- tag屬性, 告知渲染成div --> <transition-group tag="div"> <template v-for="item in nums" :key="item"> <span>{{ item }}</span> </template> </transition-group> </div> </template>
在上面的案例中雖然新增的或者刪除的節(jié)點(diǎn)是有動畫的,但是對于哪些其他需要移動的節(jié)點(diǎn)是沒有動畫的:
我們可以通過使用一個(gè)新增的 v-move 的class來完成動畫;
它會在元素改變位置的過程中應(yīng)用;
像之前的名字一樣,我們也可以通過name來自定義前綴;
/* 定位解決刪除占用空間, 無法執(zhí)行動畫問題 */ .v-leave-active { position: absolute; } /* 針對其他節(jié)點(diǎn)移動需要的動畫 */ .v-move { transition: all 2s linear; }
到此這篇關(guān)于Vue中實(shí)現(xiàn)過渡動畫效果示例代碼的文章就介紹到這了,更多相關(guān)Vue中實(shí)現(xiàn)過渡動畫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue 頁面權(quán)限控制和登陸驗(yàn)證功能的實(shí)例代碼
這篇文章主要介紹了Vue 頁面權(quán)限控制和登陸驗(yàn)證功能的實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06VUE.CLI4.0配置多頁面入口的實(shí)現(xiàn)
這篇文章主要介紹了VUE.CLI4.0配置多頁面入口的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11關(guān)于實(shí)現(xiàn)Vue3版抖音滑動插件踩坑指南
這篇文章主要給大家介紹了關(guān)于實(shí)現(xiàn)Vue3版抖音滑動插件踩坑指南,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用vue3具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02Vue項(xiàng)目中實(shí)現(xiàn)帶參跳轉(zhuǎn)功能
最近做了一個(gè)手機(jī)端系統(tǒng),其中遇到了父頁面需要攜帶參數(shù)跳轉(zhuǎn)至子頁面的問題,現(xiàn)已解決,下面分享一下實(shí)現(xiàn)過程,感興趣的朋友一起看看吧2021-04-04