日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > vue >内容正文

vue

Vue3过渡动画实现

發(fā)布時(shí)間:2024/7/5 vue 58 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue3过渡动画实现 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、認(rèn)識(shí)動(dòng)畫

在開發(fā)中,我們想要給一個(gè)組件的顯示和消失添加某種過(guò)渡動(dòng)畫,可以很好的增加用戶體驗(yàn):

  • React框架本身并沒(méi)有提供任何動(dòng)畫相關(guān)的API,所以在React中使用過(guò)渡動(dòng)畫我們需要使用一個(gè)第三方庫(kù)react-transition-group;
  • Vue中為我們提供一些內(nèi)置組件和對(duì)應(yīng)的API來(lái)完成動(dòng)畫,利用它們我們可以方便的實(shí)現(xiàn)過(guò)渡動(dòng)畫效果;

我們來(lái)看一個(gè)案例:

  • Hello World的顯示和隱藏;
  • 通過(guò)下面的代碼實(shí)現(xiàn),是不會(huì)有任何動(dòng)畫效果的;

沒(méi)有動(dòng)畫的情況下,整個(gè)內(nèi)容的顯示和隱藏會(huì)非常的生硬:

  • 如果我們希望給單元素或者組件實(shí)現(xiàn)過(guò)渡動(dòng)畫,可以使用 transition 內(nèi)置組件來(lái)完成動(dòng)畫;

二、Vue的transition動(dòng)畫

Vue 提供了 transition 的封裝組件,在下列情形中,可以給任何元素和組件添加進(jìn)入/離開過(guò)渡:

  • 條件渲染 (使用 v-if)條件展示 (使用 v-show)
  • 動(dòng)態(tài)組件
  • 組件根節(jié)點(diǎn)


<template><div><button @click="isShow = !isShow">顯示/隱藏</button><transition name="zep"><h2 v-if="isShow">Hello World</h2></transition></div> </template> <script> export default {name: "App",data() {return {isShow: true}},methods: {} } </script><style scoped>.zep-enter-from,.zep-leave-to{opacity: 0;}.zep-enter-to,.zep-leave-from{opacity: 1;}.zep-enter-active,.zep-leave-active{transition: opacity 2s ease;} </style>

三、Transition組件的原理

我們會(huì)發(fā)現(xiàn),Vue自動(dòng)給h2元素添加了動(dòng)畫,這是什么原因呢?
當(dāng)插入或刪除包含在 transition 組件中的元素時(shí),Vue 將會(huì)做以下處理:

  • 1.自動(dòng)嗅探目標(biāo)元素是否應(yīng)用了CSS過(guò)渡或者動(dòng)畫,如果有,那么在恰當(dāng)?shù)臅r(shí)機(jī)添加/刪除 CSS類名;
  • 2.如果 transition 組件提供了JavaScript鉤子函數(shù),這些鉤子函數(shù)將在恰當(dāng)?shù)臅r(shí)機(jī)被調(diào)用;
  • 3.如果沒(méi)有找到JavaScript鉤子并且也沒(méi)有檢測(cè)到CSS過(guò)渡/動(dòng)畫,DOM插入、刪除操作將會(huì)立即執(zhí)行;

那么都會(huì)添加或者刪除哪些class呢?

四、過(guò)渡動(dòng)畫class

我們會(huì)發(fā)現(xiàn)上面提到了很多個(gè)class,事實(shí)上Vue就是幫助我們?cè)谶@些class之間來(lái)回切換完成的動(dòng)畫:

  • v-enter-from:定義進(jìn)入過(guò)渡的開始狀態(tài)。在元素被插入之前生效,在元素被插入之后的下一幀移除。
  • v-enter-active:定義進(jìn)入過(guò)渡生效時(shí)的狀態(tài)。在整個(gè)進(jìn)入過(guò)渡的階段中應(yīng)用,在元素被插入之前生效,在過(guò)渡/動(dòng)畫完成之后移除。這個(gè)類可以被用來(lái)定義進(jìn)入過(guò)渡的過(guò)程時(shí)間,延遲和曲線函數(shù)。
  • v-enter-to:定義進(jìn)入過(guò)渡的結(jié)束狀態(tài)。在元素被插入之后下一幀生效 (與此同時(shí) v-enter-from 被移除),在過(guò)渡/動(dòng)畫完成之后移除。
  • v-leave-from:定義離開過(guò)渡的開始狀態(tài)。在離開過(guò)渡被觸發(fā)時(shí)立刻生效,下一幀被移除。
  • v-leave-active:定義離開過(guò)渡生效時(shí)的狀態(tài)。在整個(gè)離開過(guò)渡的階段中應(yīng)用,在離開過(guò)渡被觸發(fā)時(shí)立刻生效,在過(guò)渡/動(dòng)畫完成之后移除。這個(gè)類可以被用來(lái)定義離開過(guò)渡的過(guò)程時(shí)間,延遲和曲線函數(shù)。
  • v-leave-to:離開過(guò)渡的結(jié)束狀態(tài)。在離開過(guò)渡被觸發(fā)之后下一幀生效 (與此同時(shí) v-leave-from 被刪除),在過(guò)渡/動(dòng)畫完成之后移除。
  • 五、class添加的時(shí)機(jī)和命名規(guī)則


    class的name命名規(guī)則如下:

    • 如果我們使用的是一個(gè)沒(méi)有name的transition,那么所有的class是以 v- 作為默認(rèn)前綴
    • 如果我們添加了一個(gè)name屬性,比如 <transtion name="zep">,那么所有的class會(huì)以 zep- 開頭

    六、過(guò)渡css動(dòng)畫

    前面我們是通過(guò)transition來(lái)實(shí)現(xiàn)的動(dòng)畫效果,另外我們也可以通過(guò)animation來(lái)實(shí)現(xiàn)。


    <template><div class="app"><div><button @click="isShow = !isShow">顯示/隱藏</button></div><transition name="zep"><h2 class="title" v-if="isShow">Hello World</h2></transition></div> </template> <script> export default {name: "App",data() {return {isShow: true}},methods: {} } </script><style scoped>.app {width: 200px;margin: 0 auto;}.title {display: inline-block;}.zep-enter-active{animation: bounce 1s ease;}.zep-leave-active {animation: bounce 1s ease reverse;}@keyframes bounce {0% {transform: scale(0);}50% {transform: scale(1.2);}100% {transform: scale(1);}} </style>

    七、同時(shí)設(shè)置過(guò)渡和動(dòng)畫

    Vue為了知道過(guò)渡的完成,內(nèi)部是在監(jiān)聽(tīng) transitionend 或 animationend,到底使用哪一個(gè)取決于元素應(yīng)用的CSS規(guī)則:

    • 如果我們只是使用了其中的一個(gè),那么Vue能自動(dòng)識(shí)別類型并設(shè)置監(jiān)聽(tīng);

    但是如果我們同時(shí)使用了過(guò)渡和動(dòng)畫呢?

    • 并且在這個(gè)情況下可能某一個(gè)動(dòng)畫執(zhí)行結(jié)束時(shí),另外一個(gè)動(dòng)畫還沒(méi)有結(jié)束;
    • 在這種情況下,我們可以設(shè)置 type 屬性為 animation 或者 transition 來(lái)明確的告知Vue監(jiān)聽(tīng)的類型;

    注意:
    type值選擇animation還是transition?
    誰(shuí)的持續(xù)時(shí)間長(zhǎng)選擇誰(shuí),以確保animation還是transition都能順利執(zhí)行完

    <template><div class="app"><div><button @click="isShow = !isShow">顯示/隱藏</button></div><transition name="zep" type="transition"><h2 class="title" v-if="isShow">Hello World</h2></transition></div> </template> <script> export default {name: "App",data() {return {isShow: true}},methods: {} } </script><style scoped>.app {width: 200px;margin: 0 auto;}.title {display: inline-block;}/* 過(guò)渡動(dòng)畫 */.zep-enter-from,.zep-leave-to {opacity: 0;}.zep-enter-to,.zep-leave-from {opacity: 1;}.zep-enter-active,.zep-leave-active {transition: opacity 2s ease;}/* animation動(dòng)畫 */.zep-enter-active{animation: bounce 1s ease;}.zep-leave-active {animation: bounce 1s ease reverse;}@keyframes bounce {0% {transform: scale(0);}50% {transform: scale(1.2);}100% {transform: scale(1);}} </style>

    八、顯示的指定動(dòng)畫時(shí)間

    我們也可以顯示的來(lái)指定過(guò)渡的時(shí)間,通過(guò) duration 屬性。

    duration可以設(shè)置兩種類型的值:

    • number類型:同時(shí)設(shè)置進(jìn)入和離開的過(guò)渡時(shí)間;
    • object類型:分別設(shè)置進(jìn)入和離開的過(guò)渡時(shí)間;

    九、過(guò)渡的模式mode

    我們來(lái)看當(dāng)前的動(dòng)畫在兩個(gè)元素之間切換的時(shí)候存在的問(wèn)題:

    我們會(huì)發(fā)現(xiàn) Hello World 和 你好啊,李銀河是同時(shí)存在的:

    • 這是因?yàn)?strong>默認(rèn)情況下進(jìn)入和離開動(dòng)畫是同時(shí)發(fā)生的;
    • 如果確實(shí)我們希望達(dá)到這個(gè)的效果,那么是沒(méi)有問(wèn)題;

    但是如果我們不希望同時(shí)執(zhí)行進(jìn)入和離開動(dòng)畫,那么我們需要設(shè)置transition的過(guò)渡模式:

    • in-out: 新元素先進(jìn)行過(guò)渡,完成之后當(dāng)前元素過(guò)渡離開;

    • out-in: 當(dāng)前元素先進(jìn)行過(guò)渡,完成之后新元素過(guò)渡進(jìn)入;

    十、動(dòng)態(tài)組件的切換

    上面的示例同樣適用于我們的動(dòng)態(tài)組件:


    十一、appear初次渲染

    默認(rèn)情況下,首次渲染的時(shí)候是沒(méi)有動(dòng)畫的,如果我們希望給他添加上去動(dòng)畫,那么就可以增加另外一個(gè)屬性appear:

    十二、認(rèn)識(shí)animate.css

    如果我們手動(dòng)一個(gè)個(gè)來(lái)編寫這些動(dòng)畫,那么效率是比較低的,所以在開發(fā)中我們可能會(huì)引用一些第三方庫(kù)的動(dòng)畫庫(kù), 比如animate.css。

    什么是animate.css呢?

    • Animate.css is a library of ready-to-use, cross-browser animations for use in your web projects. Great for emphasis, home pages, sliders, and attention-guiding hints.
    • Animate.css是一個(gè)已經(jīng)準(zhǔn)備好的、跨平臺(tái)的動(dòng)畫庫(kù)為我們的web項(xiàng)目,對(duì)于強(qiáng)調(diào)、主頁(yè)、滑動(dòng)、注意力引導(dǎo)非常有用;

    如何使用Animate庫(kù)呢?
    第一步:需要安裝animate.css庫(kù);
    第二步:導(dǎo)入animate.css庫(kù)的樣式;
    第三步:使用animation動(dòng)畫或者animate提供的類;

    十三、自定義過(guò)渡class

    我們可以通過(guò)以下 attribute 來(lái)自定義過(guò)渡類名:

    • enter-from-class
    • enter-active-class
    • enter-to-class
    • leave-from-class
    • leave-active-class
    • leave-to-class

    他們的優(yōu)先級(jí)高于普通的類名,這對(duì)于 Vue 的過(guò)渡系統(tǒng)和其他第三方 CSS 動(dòng)畫庫(kù),如 Animate.css. 結(jié)合使用十 分有用

    十四、animate.css庫(kù)的使用

    安裝animate.css:

    npm install animate.css

    在main.js中導(dǎo)入animate.css:

    接下來(lái)在使用的時(shí)候我們有兩種用法:

    • 用法一:直接使用animate庫(kù)中定義的 keyframes 動(dòng)畫;

    • 用法二:直接使用animate庫(kù)提供給我們的類;

    十五、認(rèn)識(shí)gsap庫(kù)

    某些情況下我們希望通過(guò)JavaScript來(lái)實(shí)現(xiàn)一些動(dòng)畫的效果,這個(gè)時(shí)候我們可以選擇使用gsap庫(kù)來(lái)完成。

    什么是gsap呢?

    • GSAP是The GreenSock Animation Platform(GreenSock動(dòng)畫平臺(tái))的縮寫;
    • 它可以通過(guò)JavaScript為CSS屬性、SVG、Canvas等設(shè)置動(dòng)畫,并且是瀏覽器兼容的;

    這個(gè)庫(kù)應(yīng)該如何使用呢?
    第一步:需要安裝gsap庫(kù);
    第二步:導(dǎo)入gsap庫(kù); p第三步:使用對(duì)應(yīng)的api即可;

    我們可以先安裝一下gsap庫(kù):

    npm install gsap

    十六、JavaScript鉤子

    在使用動(dòng)畫之前,我們先來(lái)看一下transition組件給我們提供的JavaScript鉤子,這些鉤子可以幫助我們監(jiān)聽(tīng)動(dòng)畫執(zhí)行到 什么階段了。


    <template><div class="app"><div><button @click="isShow = !isShow">顯示/隱藏</button></div><transition@before-enter="beforeEnter"@enter="enter"@after-enter="afterEnter"@before-leave="beforeLeave"@leave="leave"@after-leave="afterLeave"><h2 class="title" v-if="isShow">hello</h2></transition></div> </template> <script>export default {name: "App",data() {return {isShow: true}},methods: {beforeEnter() {console.log('beforeEnter')},enter() {console.log('enter')},afterEnter() {console.log('afterEnter')},beforeLeave() {console.log('beforeLeave')},leave() {console.log('leave')},afterLeave() {console.log('afterLeave')}} } </script> <style scoped> .title {display: inline-block; } </style>

    當(dāng)我們使用JavaScript來(lái)執(zhí)行過(guò)渡動(dòng)畫時(shí),需要進(jìn)行 done 回調(diào),否則它們將會(huì)被同步調(diào)用,過(guò)渡會(huì)立即完成。

    添加 :css=“false”,也會(huì)讓 Vue 會(huì)跳過(guò) CSS 的檢測(cè),除了性能略高之外,這可以避免過(guò)渡過(guò)程中 CSS 規(guī)則的影響。

    十七、gsap庫(kù)的使用

    那么接下來(lái)我們就可以結(jié)合gsap庫(kù)來(lái)完成動(dòng)畫效果:

    十八、gsap實(shí)現(xiàn)數(shù)字變化

    在一些項(xiàng)目中,我們會(huì)見(jiàn)到數(shù)字快速變化的動(dòng)畫效果,這個(gè)動(dòng)畫可以很容易通過(guò)gsap來(lái)實(shí)現(xiàn):

    <template><div class="app"><input type="number" step="100" v-model="counter"><h2>{{showCounter}}</h2><h2>{{showNumber.toFixed(0)}}</h2></div> </template> <script> import gsap from 'gsap' export default {name: "App",data() {return {counter: 0,showNumber: 0}},computed: {showCounter () {return this.showNumber.toFixed(0)}},watch: {counter(newValue) {gsap.to(this, {duration: 1,showNumber: newValue})}} } </script> <style scoped> </style>

    十九、認(rèn)識(shí)列表的過(guò)渡

    目前為止,過(guò)渡動(dòng)畫我們只要是針對(duì)單個(gè)元素或者組件的:

    • 要么是單個(gè)節(jié)點(diǎn);
    • 要么是同一時(shí)間渲染多個(gè)節(jié)點(diǎn)中的一個(gè);

    那么如果希望渲染的是一個(gè)列表,并且該列表中添加刪除數(shù)據(jù)也希望有動(dòng)畫執(zhí)行呢?

    • 這個(gè)時(shí)候我們要使用 <transition-group> 組件來(lái)完成;

    使用<transition-group> 有如下的特點(diǎn):

    • 默認(rèn)情況下,它不會(huì)渲染一個(gè)元素的包裹器,但是你可以指定一個(gè)元素并以 tag attribute 進(jìn)行渲染;
    • 過(guò)渡模式不可用,因?yàn)槲覀儾辉傧嗷デ袚Q特有的元素;
    • 內(nèi)部元素總是需要提供唯一的 key attribute 值;
    • CSS 過(guò)渡的類將會(huì)應(yīng)用在內(nèi)部的元素中,而不是這個(gè)組/容器本身;

    二十、列表過(guò)渡的基本使用

    我們來(lái)做一個(gè)案例:

    • 案例是一列數(shù)字,可以繼續(xù)添加或者刪除數(shù)字;
    • 在添加和刪除數(shù)字的過(guò)程中,對(duì)添加的或者移除的數(shù)字添加動(dòng)畫;
    <template><div class="app"><button @click="addNum">添加數(shù)字</button><button @click="removeNum">刪除數(shù)字</button><transition-group tag="p" name="zep"><span class="item" v-for="item in numbers" :key="item">{{item}}</span></transition-group></div> </template> <script> export default {name: "App",data() {return {numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],numCounter: 10}},methods: {addNum () {this.numbers.splice(this.randomIndex(), 0, this.numCounter++)},removeNum () {this.numbers.splice(this.randomIndex(), 1)},randomIndex() {return Math.floor(Math.random() * this.numbers.length)}} } </script> <style scoped>.item {margin-right: 10px;display: inline-block;}.zep-enter-from,.zep-leave-to {opacity: 0;transform: translateY(30px);}.zep-enter-to,.zep-leave-from {opacity: 1;transform: translateY(0px);}.zep-enter-active,.zep-leave-active {transition: all 1s ease;} </style>

    二十一、列表過(guò)渡的移動(dòng)動(dòng)畫

    在上面的案例中雖然新增的或者刪除的節(jié)點(diǎn)是有動(dòng)畫的,但是對(duì)于哪些其他需要移動(dòng)的節(jié)點(diǎn)是沒(méi)有動(dòng)畫的:

    • 我們可以通過(guò)使用一個(gè)新增的 v-move 的class來(lái)完成動(dòng)畫;
    • 它會(huì)在元素改變位置的過(guò)程中應(yīng)用;
    • 像之前的名字一樣,我們可以通過(guò)name來(lái)自定義前綴;

      增加洗牌效果:
    <template><div class="app"><button @click="addNum">添加數(shù)字</button><button @click="removeNum">刪除數(shù)字</button><button @click="shuffleNum">洗牌</button><transition-group tag="p" name="zep"><span class="item" v-for="item in numbers" :key="item">{{item}}</span></transition-group></div> </template> <script> import gsap from 'gsap' import _ from 'lodash' export default {name: "App",data() {return {numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],numCounter: 10}},methods: {addNum () {this.numbers.splice(this.randomIndex(), 0, this.numCounter++)},removeNum () {this.numbers.splice(this.randomIndex(), 1)},randomIndex() {return Math.floor(Math.random() * this.numbers.length)},shuffleNum() {this.numbers = _.shuffle(this.numbers)}} } </script> <style scoped>.item {margin-right: 10px;display: inline-block;}.zep-enter-from,.zep-leave-to {opacity: 0;transform: translateY(30px);}.zep-enter-to,.zep-leave-from {opacity: 1;transform: translateY(0px);}.zep-enter-active,.zep-leave-active {transition: all 1s ease;}.zep-leave-active {position: absolute;}.zep-move {transition: transform 1s ease;} </style>

    二十二、列表的交錯(cuò)過(guò)渡案例

    使用css過(guò)渡動(dòng)畫:達(dá)不到一個(gè)一個(gè)消失的效果,而是全部一起消失

    我們來(lái)通過(guò)gsap的延遲delay屬性,做一個(gè)交替消失的動(dòng)畫:

    <template><div class="app"><input type="text" v-model="keyword"><transition-group tag="ul" name="zep" :css="false"@before-enter="beforeEnter"@enter="enter"@leave="leave"><li v-for="(item, index) in showNames" :data-index="index" :key="item">{{item}}</li></transition-group></div> </template> <script> import gsap from 'gsap' export default {name: "App",data() {return {names: ['abc', 'cba', 'nba', 'why', 'lilei', 'bob', 'zep'],keyword: ''}},computed: {showNames() {return this.names.filter((item) => {return item.indexOf(this.keyword) !== -1})}},methods: {beforeEnter (el) {el.style.opacity = 0el.style.height = 0},enter (el, done) {gsap.to(el, {opacity: 1,height: '1.5rem',delay: el.dataset.index * 0.5,onComplete: done})},leave (el, done) {gsap.to(el, {opacity: 0,height: '0rem',delay: el.dataset.index * 0.5,onComplete: done})}} } </script> <style scoped>/* .zep-enter-from,.zep-leave-to {opacity: 0;}.zep-enter-active,.zep-leave-active {transition: opacity 1s ease;} */ </style>

    總結(jié)

    以上是生活随笔為你收集整理的Vue3过渡动画实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。