【坑】解决vant的列表组件因数据过多而导致的渲染卡顿问题

问题出现情景

这次的项目要开发一个移动端的产品,要求列表滚动展示,有下拉刷新功能,上滑到底部继续加载,一直滑动一直加载。我采用的是vant组件库。

由于列表要展示图片,当大概加载了百来条数据就会出现卡顿不流畅的现象。因为刚开始的时候加载十分流畅,越往下滑越卡顿,所以猜测不是请求发送的问题,而是渲染DOM的问题,越滑动DOM树积累越多,导致页面不流畅。

我在网上搜索到了类似的问题解决方案,基本上是说去实现虚拟滚动,只显示设备屏幕范围的内容,其上下看不到的数据不进行渲染,可以提高效率。

难受的是我并没有找到vant组件支持的方案,官方文档的list组件只有往数组里push的功能,没有任何优化,网上也没搜到有人使用vant列表出现过类似的问题。

我还搜到了一个叫vue-virtual-scroller的组件库,可以实现虚拟滚动,正当我打算尝试把这个组件和van-list结合使用的时候,发现光是引用vue-virtual-scroller编译器就开始报错了。

在这里插入图片描述
目前没来得及解决这个问题,不知道有没有大神能帮忙看一看。不过我干脆就不引入了,一不做二不休,手撕吧。

获取scroll的数值

要想隐藏设备显示区域之外的内容,就要先获取到滚轮的位置,这样就能通过滚动的长度来判断列表是否在屏幕显示外侧。

但是在哪里能获取到scrollTop呢……经过多次尝试,发现滚轮的值根本不在van-list上,如果你使用了van-pull-refresh,scroll的值在这个组件里面。

给组件加一个 ref=“refresh”,就可以调用this.$refs.refresh.scrollEl.scrollY来获取scroll的值。

如何触发滚动事件

拿到scroll的值还算好说,然而这个值你直接获取只能拿到一次,如何才能实时监测值的变化呢?

一般来说组件应当有个滚动即触发的方法,最坑的是,官方文档上啥都没写,网上也搜不到,最后我依旧是在van-pull-refresh组件里乱翻它内部的方法,然后瞎勾巴试,发现它居然是有滚动触发的方法的!就是 $refs.refresh.scrollEl.scroll ,给这个方法添加函数调用就可以,官方居然没写!也没给组件功能做接口!

显示内容的条件

滚轮最开始的值为0,往下滚动逐渐增加,可以通过调试取一个大概的范围,让scroll的值在某一范围内时,显示某一项。

设列表行高100px,每多一项都要在有效范围+100,这里要用到v-for循环的index来辅助计算。

代码

首先写一个函数,获取scroll的值。

onScroll() {
    
    
  this.showItemDis = this.$refs.refresh.scrollEl.scrollY
}

然后在mounted获取组件实例,将函数赋值过去,实现每次滚动都调用onScroll()。

mounted() {
    
    
  this.$refs.refresh.scrollEl.addEventListener('scroll', this.onScroll)
},

根据每次滚动取到的值,用v-if来判断是否显示列表某一项。

<div class="list" id="list">
  <van-pull-refresh v-model="listRefreshing" @refresh="onRefresh" ref="refresh">
    <van-list v-model="listLoading" :finished="listFinished" finished-text="没有更多了" @refresh="onRefresh"
          @load="onLoad">
      <div v-for="(item, index) in listData" :key="index" :class="'cell-item ' + index">
        <van-cell v-if="(showItemDis < 1500 + (index + 1) * 100) && (showItemDis + 1500 > (index + 1) * 100)" clickable :to="'Details?table=2&id=' + item.id">
        <!-- 列表每列内容 -->
        </van-cell>
      </div>
    </van-list>
  </van-pull-refresh>
</div>

重点是van-cell的v-if条件,我这里每列设置的是100px,所以相当于显示上15条和下15条,大概理解一下就行。

还有一点一定要注意,包住van-cell的那个div一定要设置高度,不然div里面的van-cell一旦不渲染,高度就会缩小,滚轮的值也会变,会出现抽搐现象。

猜你喜欢

转载自blog.csdn.net/DrLemonPie/article/details/129319043
今日推荐