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 获取到正确的内容,具体区分项目

描述有点乱,但愿能给也遇到此问题的朋友提供一个思路,有误的地方麻烦你们及时指正。

相关文章
相关标签/搜索