日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

如何在Vue中實現Svelte的Defer Transition

瀏覽:31日期:2022-09-30 17:19:02

最近觀看了Rich Harris的<Rethinking Reactivity>視頻,驚嘆于Svelte框架的高效同時,還發現了Vue所不具備的一些關于動畫的原生支持—defer transitions.

先看看Svelte所謂的defer transition的效果吧。

如何在Vue中實現Svelte的Defer Transition

這是使用Svelte做的Todo Demo應用。整個todo分成3個部分。輸入部分,todo列表和done列表。當點擊todo列表中的條目時,相應條目會被“移動”到done列表,反之亦然。

在這里,條目從一個列表轉移到另一個列表,不是很突兀的閃現,而是非常友好地從點擊處,移動到目的地;同時,當列表中條目離開時,剩余的條目會絲滑地向上移動填補空缺的位置。在Svelte里,只需要僅僅加上幾行代碼,就能實現,對于開發者非常友好且高效。 參考如下代碼或者Svelte教程

{#each todos.filter(t => !t.done) as todo (todo.id)} <labelin:receive='{{key: todo.id}}'out:send='{{key: todo.id}}'animate:flip><input type=checkbox on:change={() => mark(todo, true)}> {todo.description} <button on:click='{() => remove(todo)}'>remove</button> </label>{/each}

僅僅在element上加上了in、out和animate屬性。這里,in和out各自接受框架提供的函數receive和send并且給他們提供了篩選條件。 animate屬性接收內置的flip方法。這里的flip不是翻轉,而是FLIP技術技術,vue在<transition-group>中也有用到。主要用于整體移動列表剩余條目去填補所失去元素的位置。

于是我就在想,如果是Vue的話,如何能達到相應的效果呢。 (不想看詳細說明的話,可以直接查看code pen中的代碼)

Vue原生提供了兩個組件支持動畫。transition和transition-group。由于是list的移動,所以我們這里使用transition-group。具體使用方法可以參考Vue教程Transitions & Animation。

要想達到同樣的效果,有兩大UI動畫效果要實現。

列表中條目消失時,剩余條目移動補齊空位條目消失同時在另外一個列表插入時,條目移動第一個需求的實現比較簡單,vue原生已經提供了良好的支持,參考Vue文檔中的List-Move-Transitions即可

為了實現第二個需求,有幾個問題必須解決:

消失條目的位置信息 插入條目的位置信息 動效開始與結束的時機

我們先看看前兩個問題的如何解決。根據文檔的介紹,transition-group提供了javascript hook。分別是:

v-on:before-enter v-on:enter v-on:after-enter v-on:enter-cancelled v-on:before-leave v-on:leave v-on:after-leave v-on:leave-cancelled

可視化表示的話,大概是如下圖所示:

如何在Vue中實現Svelte的Defer Transition

before-enter: 用于設置插入條目的transition的初始值。此時無法獲取BoundingClientRect. enter: 動效期。此時enter鉤子函數的入參el能獲取boundingClientRect after-enter: 動效結束后的回調函數 enter-cancelled: 取消enter的鉤子

leave也是類似。

所以,我們能拿到條目元素DOMRect信息的時機只有enter和leave的時候。

這樣,我們就可以在leave時候,拿到leave條目的DOMRect數據并且保存起來。在enter的時候, 我們就能同時擁有leave條目和enter條目的位置信息了。

位置信息是拿到了,那怎么才能在條目進入的時候,有從消失條目移動過來的效果呢。(可以先想想, 再看后面的解釋)。

所以,我們想要達成移動的效果,首先需要隱藏掉leave條目元素,

leave(el, done) { console.log('before leave'); const rect = el.getBoundingClientRect(); sendRectMap.set(el.dataset.key, rect); el.style.display = 'none';},

然后給enter條目元素設定關于位置初始狀態,初始化的位置即為leave條目元素的位置,然后當transition開始生效的時候,讓其位置恢復到插入(enter)的位置。

這種方法其實就是所謂的FLIP技術。transition-group組件里也使用了這種技術來移動剩余列表填充移走條目空白。

var first = el.getBoundingClientRect();// Now set the element to the last position.el.classList.add(’totes-at-the-end’);// Read again. This forces a sync// layout, so be careful.var last = el.getBoundingClientRect();// You can do this for other computed// styles as well, if needed. Just be// sure to stick to compositor-only// props like transform and opacity// where possible.var invert = first.top - last.top;// Invert.el.style.transform = `translateY(${invert}px)`;// Wait for the next frame so we// know all the style changes have// taken hold.requestAnimationFrame(function() { // Switch on animations. el.classList.add(’animate-on-transforms’); // GO GO GOOOOOO! el.style.transform = ’’;});

那么接下來的問題就是,在什么時機去設置enter條目元素transition的初始狀態,在什么時機去設置enter條目元素transition的結束時狀態。

按照上面提到的javascript hook,我們可以在before-enter鉤子函數里設置初始狀態,接著在enter鉤子函數里設置transition結束狀態。那么,我們的初始狀態是什么呢?我們通過getBoundingClientRect,可以獲取到enter元素(后用to來標識)的DOMRect數據,包括top, left, bottom, right, width, height , x, y。 同時我們也能通過之前保存的leave位置map獲取到leave條目的位置信息(稱為from)。所以在before-enter時,我們通過計算得到的偏移量,通過translate去初始化to元素的位置。然后再在enter階段,translate其值到from, 再加上transition到css中即可。

在before-enter鉤子中:

// 移動元素的標識符const key = el.dataset.key;// enter條目 map,注意這里,在before-enter鉤子中,// receiveRectMap是get不到to的。需要特殊處理。后面有提及const to = receiveRectMap.get(key);// leave條目 mapconst from = sendRectMap.get(key);// 計算偏移量const dx = from.left - to.left;const dy = from.top - to.top;// 初始化to條目的位置el.style.transform = `translate(${dx}px, ${dy}px)`;el.style.opacity = 0;

在enter鉤子中:

el.style.transition = 'all 800ms';el.style.transform = '';el.style.opacity = 1;el.style.display = 'block';

上面的代碼中,在before-enter里面,to是通過receiveRectMap.get(key)來獲取的。但是,這時,receiveRectMap中還沒有對應key的DOMRect值。雖然,before-enter的入參是el(HTMLElement),但是該el元素的DOMRect中的所有值都為0,所以我們需要在enter方法中,把el塞入到receiveRectMap中。這樣就會有一個矛盾,那就是無法在before-enter中通過translate初始化to元素的位置了。所以,我們這里使用defer transition技術,延遲transition的發生。

我們可以在enter中使用setTimeout或者requestAnimationFrame實現defer transition,

requestAnimationFrame(() => {const key = el.dataset.key; // 這樣,receiveRectMap中就有該key的值了。const to = receiveRectMap.get(key);const from = sendRectMap.get(key);const dx = from.left - to.left;const dy = from.top - to.top;// 由于我們延遲了transition的發生,// 所以to元素的位置其實已經到達了目的地位置,// 所以我們需要使用transition手動地將其過渡到from位置,這一行很重要el.style.transition = 'all 0ms';el.style.transform = `translate(${dx}px, ${dy}px)`;// 初始化結束后,在下一個animation frame中,使用FLIP技術,使其移動回來。requestAnimationFrame(() => { el.style.transition = 'all 800ms'; el.style.transform = ''; el.style.opacity = 1; el.style.display = 'block';}); });

完整代碼可以參考codepen

最后效果:

如何在Vue中實現Svelte的Defer Transition

以上就是如何在Vue中實現Svelte的Defer Transition的詳細內容,更多關于Vue 實現Svelte的Defer Transition的資料請關注好吧啦網其它相關文章!

標簽: Vue
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日韩欧乱色一区二区三区在线| 91久久久精品国产| 欧洲精品一区二区三区| 国产欧美一区| 国产欧美日韩精品一区二区三区| 国产一区导航| 视频一区二区三区在线| 亚洲精品在线二区| 青青草国产成人99久久| 欧美亚洲综合视频| 国产精品久久久久久妇女| 国产精品久久久久久久久免费高清| 日韩国产91| 午夜天堂精品久久久久| 日韩av中文字幕一区| 一区二区不卡| 蜜桃91丨九色丨蝌蚪91桃色| 中文亚洲免费| 天堂va在线高清一区| 欧美黄色一区二区| 久久人人88| 久久国内精品视频| 国产成人精品一区二区三区免费| 在线人成日本视频| 国产视频一区免费看| 国产欧美三级| 久久一区二区中文字幕| 中文在线一区| 国产精品99久久免费观看| 国产精品美女在线观看直播| 日韩专区精品| 日韩在线麻豆| 99久久九九| 国产精品久久久久9999高清| 欧美日韩中文字幕一区二区三区| 日韩欧美另类中文字幕| 久久久久久久久99精品大| 18国产精品| 美女精品在线观看| 国产+成+人+亚洲欧洲在线| 国产一区导航| 国产高清不卡| 精品视频97| 精品中文字幕一区二区三区 | 欧美日韩水蜜桃| 久久精品 人人爱| 999在线观看精品免费不卡网站| 国产精品18| 日韩1区2区日韩1区2区| 欧美日韩少妇| 日韩不卡在线| 精品三级av| 国产亚洲精品美女久久| 亚洲欧美日本日韩| 欧美综合另类| 亚洲一区二区三区免费在线观看| 国产精品老牛| 老牛影视一区二区三区| 国产精品v一区二区三区| 亚洲精品伊人| 日韩激情一区二区| 日本一区二区中文字幕| 亚洲另类黄色| 亚洲毛片视频| 亚洲精品第一| 日本不卡一区二区三区| 激情自拍一区| 亚洲成人不卡| 精品久久一区| 国产自产自拍视频在线观看| 国产精品任我爽爆在线播放| 69精品国产久热在线观看| 日韩福利视频一区| 国产精品一区二区精品| 欧美激情麻豆| 国产精品毛片久久久| 精品女同一区二区三区在线观看| 国产精品777777在线播放 | 麻豆精品视频在线| 美女久久久精品| 精品久久不卡| 一区二区亚洲精品| 91精品在线免费视频| 91视频久久| 正在播放日韩精品| 欧美福利一区| 国产精品激情电影| 亚洲h色精品| 日本不卡一区二区三区| 国产精品久久观看| 夜久久久久久| 日韩和欧美一区二区三区| 国产成人1区| 91精品一区二区三区综合在线爱| 99视频精品| 麻豆国产精品| 伊人精品一区| 欧美精品aa| 久久福利一区| 精品久久91| 丝袜诱惑制服诱惑色一区在线观看| 亚洲毛片在线| 中文字幕成在线观看| 自由日本语亚洲人高潮| 日韩黄色在线观看| 99成人超碰| 欧美精品国产白浆久久久久| 国产一区二区三区自拍| 久久精品福利| 欧美一级二级三级视频| 久久午夜影视| 亚洲二区精品| 麻豆精品在线| 国产一卡不卡| 亚洲性视频h| 夜鲁夜鲁夜鲁视频在线播放| 国产视频一区二区在线播放| 伊人久久成人| 99久久夜色精品国产亚洲狼 | 国产高清视频一区二区| 日韩不卡视频在线观看| 国产中文字幕一区二区三区| 91p九色成人| 日本不卡一二三区黄网| 深夜视频一区二区| 欧产日产国产精品视频| 欧美国产日本| 四虎8848精品成人免费网站 | 久久福利毛片| 免费日本视频一区| 亚洲综合小说| 91精品国产自产观看在线 | 爽爽淫人综合网网站| 视频一区欧美日韩| 亚洲天堂免费| 日韩中文一区二区| 日本国产一区| 国产欧美大片| 国产成人免费av一区二区午夜| 成人台湾亚洲精品一区二区| 最近高清中文在线字幕在线观看1| 日韩精品首页| 蜜桃伊人久久| 久久不见久久见国语| 理论片午夜视频在线观看| 久久精品在线| 99视频一区| 国产精品一页| 欧美xxxx性| 亚洲一区二区三区中文字幕在线观看| 亚洲尤物在线| 亚洲人成精品久久久| 欧美日韩精品一区二区三区视频 | 影视先锋久久| 欧美日韩一区二区三区四区在线观看| 捆绑调教美女网站视频一区 | 日本综合精品一区| 电影天堂国产精品| 日本麻豆一区二区三区视频| 日韩一区电影| 日韩精品第一| 在线看片不卡| 国产乱码精品一区二区亚洲| 91一区二区| 欧美自拍一区| 秋霞国产精品| 国产精品极品在线观看| 欧洲亚洲一区二区三区| 色8久久久久| 激情婷婷亚洲| 精品视频一区二区三区在线观看 | 999国产精品| 精品视频一区二区三区在线观看 | 日韩欧美一区二区三区免费观看| 蜜臀av性久久久久蜜臀aⅴ四虎| 麻豆精品视频在线观看视频| 99国产成+人+综合+亚洲欧美| 日本一区二区高清不卡| 91久久精品无嫩草影院| 三级一区在线视频先锋| 亚洲电影在线| 国产自产自拍视频在线观看| 久久精品999| 日韩精品国产欧美| 鲁大师影院一区二区三区| 久久免费国产| 日韩在线综合| 国产精品网站在线看| 91精品一区| 日本不卡一区二区| 免费国产亚洲视频| 黄色亚洲精品| 99久久99久久精品国产片果冰 | 亚洲人亚洲人色久| 国产一级久久| 自拍日韩欧美| 伊人久久成人| 成人在线超碰| 色欧美自拍视频| 欧美aa在线观看|