遗世独立的梦见亭

  • 回首
  • 求索
    • 技术学习
    • 绘画学习
    • 建站日志
  • 消愁
    • 鸡尾酒
    • 旅游日记
    • 美酒品鉴笔记
  • 归梦
    • 游戏杂谈
    • 游戏开发日志
  • 闲笔
    • 小说创作
    • 胡言乱语
  • 入世
    • 工作笔记
遗世独立的梦见亭
  1. 首页
  2. 工作踩坑记
  3. 正文

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

2023年3月3日 1433点热度 0人点赞 0条评论

问题出现情景

这次的项目要开发一个移动端的产品,要求列表滚动展示,有下拉刷新功能,上滑到底部继续加载,一直滑动一直加载。我采用的是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一旦不渲染,高度就会缩小,滚轮的值也会变,会出现抽搐现象。

本作品采用 知识共享署名-非商业性使用 4.0 国际许可协议 进行许可
标签: vant Vue 学习 工作踩坑 笔记
最后更新:2023年4月26日

曦染

一个浪漫主义者的死。

打赏 点赞
< 上一篇
下一篇 >

文章评论

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回复

曦染

一个浪漫主义者的死。

文章目录
  • 问题出现情景
  • 获取scroll的数值
  • 如何触发滚动事件
  • 显示内容的条件
  • 代码
标签聚合
工作踩坑 学习 Vue 笔记 CSS vant element-ui 绘画 cookie 基础
最新 热点 随机
最新 热点 随机
黑湖 2024.10.19 京A 8×8啤酒节 【坑】使用formdata-polyfill兼容iOS系统的FormData 【学习】解决axios前端设置cookie跨域不携带的问题 没有什么天长地久 2023.10.14 京A 8×8啤酒节
谨记人生的惨痛经历 【建站日志】鸡尾酒酒谱页面已更新完毕 【资源下载】个人收藏的绘画学习资料pdf合集 2023.10.14 京A 8×8啤酒节 没有什么天长地久 【建站日志】他妈的怎么我管理员密码变了

COPYRIGHT © 2022 遗世独立的梦见亭. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

京ICP备2022007681号-1