Vue 列表上下過渡效果

前言

最近有個需求,一個列表上下移動要有簡單過渡效果,在網上找了找沒找到,多是我搜的關鍵詞不對?vue

試了試 Vue 的transition-group,也沒有達到預期的效果,而後就花了點時間作了一個操做Demo。git

項目源碼

在線演示:jsrun.net/hdyKpgithub

Demo源碼:github.com/thinkupp/vu…bash

最終效果

某列的數據由 X 位置上升到 Y 位置的過渡效果動畫

技術點

  • visibility: hidden
  • v-for key
  • 這麼簡單的實現哪有什麼技術點,哈哈哈

實現方式

這個過渡效果一共由三部分組成:ui

  • Y行位置插入X行位置的數據,添加一個高度展開效果,並使該行的數據不可見
  • X行數據不可見, 並添加一個高度收起效果
  • 原地克隆X行的DOM, 設置爲固定定位fixedtop取X行距離body的位置(offsetTop), 並作一個向上移動效果到Y行位置

這裏僅僅依靠`offsetTop`並不許確,具體見文章後面的內容. url

來看一個放慢版的效果,加了個邊框而且沒有設置visibility屬性,看的會更明瞭:spa

簡單說一下。.net

第一部分描述一個讓目標位置底下全部行有一個向下移動的過程。3d

第二部分描述那個移動的行消失的過程。

第三部分描述一個移動的過程。

爲了避免污染數據渲染出來的視圖,除了固定定位的那個盒子是直接操做DOM,以外的兩個效果是經過操做數據+類名實現的。

遇到的問題

  • 圖片閃爍問題

緣由:因爲 v-for 的時候給每行的keyindex,數據源發生變化後會致使受影響的元素的index也發生改變。

解決:將key的值由index更換爲item(惟一值, 在這裏item指的是圖片url) 。

  • 頻繁更新數據問題

當位置頻繁改變的時候要清除上一次的動畫遺留元素,否則元素會發生各類錯亂,這個很容易想的到,錯誤演示就不錄了,看一下完成的效果。

  • Duplicate keys detected

緣由:第一部分插入X行數據形成,由於兩條相同的數據重複的item會形成重複的key

解決:在進行第一部分的時候將原來那一行的key改成其它值。

<li :key="closeIndex === index ? Date.now() : item"></li>
複製代碼

我用的時間戳,其實理論上來說只要能保持惟一寫什麼均可以,反正這一行數據將在動畫結束後從數據中刪除。

  • 距離Body距離計算

僅僅依靠offsetTop計算位置是不許確的,當頁面發生滾動後元素與Body的實際距離就不是offsetTop的值了。應該用offsetTop減去scrollTop,這樣纔是元素當前與Body的實際距離。

/*
  * 計算盒子當前距離body的距離
  * @param {HTMLElement} ele 要計算位置的盒子
  * @returns {number} 當前位置距離body的距離
  * */
  calcTop(ele) {
    let offsetTop = ele.offsetTop;
    let offsetParent = ele.offsetParent;

    while (offsetParent) {
      offsetTop += offsetParent.offsetTop;
      offsetParent = offsetParent.offsetParent;
    }

    return offsetTop - (document.body.scrollTop || document.documentElement.scrollTop)
  }
複製代碼

獲取 scrollTop 的方式根據項目不一樣也不一樣,並非全部的狀況下均可以經過 document.body.scrollTop || document.documentElement.scrollTop 獲取到正確的內容,具體區分項目

描述有點亂,但願能給也遇到此問題的朋友提供一個思路,有誤的地方麻煩你們及時指正。

相關文章
相關標籤/搜索