国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

node.js|vue.js|jquery|angularjs|React|json|js教程|

服務器之家 - 編程語言 - JavaScript - vue.js - 如何在Vue中實現Svelte的Defer Transition

如何在Vue中實現Svelte的Defer Transition

2022-02-28 16:17Jayden.李 vue.js

這篇文章主要介紹了如何在Vue中實現Svelte的Defer Transition,幫助大家更好的理解和學習使用vue,感興趣的朋友可以了解下

最近觀看了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教程

?
1
2
3
4
5
6
7
8
9
10
{#each todos.filter(t => !t.done) as todo (todo.id)}
    <label
    in: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即可

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

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

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

?
1
2
3
4
5
6
7
8
9
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條目元素,

?
1
2
3
4
5
6
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組件里也使用了這種技術來移動剩余列表填充移走條目空白。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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鉤子中:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 移動元素的標識符
const key = el.dataset.key;
// enter條目 map,注意這里,在before-enter鉤子中,
// receiveRectMap是get不到to的。需要特殊處理。后面有提及
const to = receiveRectMap.get(key);
// leave條目 map
const 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鉤子中:

?
1
2
3
4
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,

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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的資料請關注服務器之家其它相關文章!

原文鏈接:https://juejin.cn/post/6949441502321836046

延伸 · 閱讀

精彩推薦
  • vue.jsVue多選列表組件深入詳解

    Vue多選列表組件深入詳解

    這篇文章主要介紹了Vue多選列表組件深入詳解,這個是vue的基本組件,有需要的同學可以研究下...

    yukiwu6752022-01-25
  • vue.jsVue2.x-使用防抖以及節流的示例

    Vue2.x-使用防抖以及節流的示例

    這篇文章主要介紹了Vue2.x-使用防抖以及節流的示例,幫助大家更好的理解和學習使用vue框架,感興趣的朋友可以了解下...

    Kyara6372022-01-25
  • vue.js詳解vue 表單綁定與組件

    詳解vue 表單綁定與組件

    這篇文章主要介紹了vue 表單綁定與組件的相關資料,幫助大家更好的理解和學習使用vue框架,感興趣的朋友可以了解下...

    Latteitcjz6432022-02-12
  • vue.js用vite搭建vue3應用的實現方法

    用vite搭建vue3應用的實現方法

    這篇文章主要介紹了用vite搭建vue3應用的實現方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下...

    Asiter7912022-01-22
  • vue.js梳理一下vue中的生命周期

    梳理一下vue中的生命周期

    看過很多人講vue的生命周期,但總是被繞的云里霧里,尤其是自學的同學,可能js的基礎也不是太牢固,聽起來更是吃力,那我就已個人之淺見,以大白話...

    CRMEB技術團隊7992021-12-22
  • vue.jsVue中引入svg圖標的兩種方式

    Vue中引入svg圖標的兩種方式

    這篇文章主要給大家介紹了關于Vue中引入svg圖標的兩種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的...

    十里不故夢10222021-12-31
  • vue.jsVue2.x 項目性能優化之代碼優化的實現

    Vue2.x 項目性能優化之代碼優化的實現

    這篇文章主要介紹了Vue2.x 項目性能優化之代碼優化的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋...

    優小U9632022-02-21
  • vue.jsVue項目中實現帶參跳轉功能

    Vue項目中實現帶參跳轉功能

    最近做了一個手機端系統,其中遇到了父頁面需要攜帶參數跳轉至子頁面的問題,現已解決,下面分享一下實現過程,感興趣的朋友一起看看吧...

    YiluRen丶4302022-03-03
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产精品观看 | 男人天堂亚洲 | 日韩欧美网站 | 欧美二区在线 | 久久综合成人精品亚洲另类欧美 | www.国产精品 | 亚洲网在线 | 亚洲国产精品成人 | 亚洲综合色视频在线观看 | 中文字幕av一区二区三区 | 97国产精品| 日韩亚洲一区二区 | 亚洲精品久久久久久一区二区 | 91在线免费视频 | 国产一区不卡 | 日韩高清在线 | 中文字幕av一区二区三区 | 日韩免费视频 | 中文字幕久久精品 | 欧美不卡在线 | a成人| 午夜精品一区 | 99黄色片 | 男人天堂亚洲 | 欧美成人综合视频 | 日韩国产免费观看 | 免费观看的av | 超碰一区二区三区 | 欧美精品一区二区视频 | 欧美一区二区三区视频 | 日韩视频在线观看 | 午夜精品久久久久 | 伊人久久婷婷色综合98网 | av影院在线观看 | 欧美一区 | 在线欧美一区 | 欧美一区二区三区久久久久久桃花 | www.国产一区 | 成人久久久精品乱码一区二区三区 | 久久久精品综合 | 在线无码 |