我写了一个代码实现了uniapp的虚拟列表滚动加载,
代码说明:
totalItems:整个列表的数据,示例中用的是 1000 条数据。
visibleItemCount:设定在可视区域最多显示的条目数。
buffer:设定滚动缓冲区,这样可以在实际滚动时减少抖动。
visibleItems:计算当前需要显示的条目,截取 totalItems 的一部分。
topBlankHeight 和 bottomBlankHeight:计算上下两部分占位的空白高度
<template> <view class="container"> <scroll-view class="scroll-view" scroll-y @scroll="onScroll" :scroll-top="scrollTop" > <!-- 占位的顶部空白区域 --> <view :style="{ height: topBlankHeight + 'px' }"></view> <!-- 实际显示的内容 --> <view v-for="(item, index) in visibleItems" :key="item.id" class="item" > {{ item.text }} </view> <!-- 占位的底部空白区域 --> <view :style="{ height: bottomBlankHeight + 'px' }"></view> </scroll-view> </view> </template> <script> export default { data() { return { totalItems: [], // 原始数据 itemHeight: 60, // 每个item的高度 visibleItemCount: 15, // 可视区域最多显示的item数量 buffer: 10, // 缓冲区,较大缓冲减少抖动 startIdx: 0, // 可视区域起始索引 scrollTop: 0, // 滚动位置 }; }, computed: { visibleItems() { return this.totalItems.slice( this.startIdx, this.startIdx + this.visibleItemCount + this.buffer ); }, topBlankHeight() { return this.startIdx * this.itemHeight; }, bottomBlankHeight() { const remainingItems = this.totalItems.length - (this.startIdx + this.visibleItems.length); return remainingItems * this.itemHeight; }, }, methods: { onScroll: throttle(function (e) { const scrollTop = e.detail.scrollTop; const currentIdx = Math.floor(scrollTop / this.itemHeight); // 仅在距离足够大时更新startIdx,避免频繁更新 if (Math.abs(currentIdx - this.startIdx) > this.buffer / 2) { this.startIdx = currentIdx - this.buffer / 2; this.startIdx = Math.max(0, this.startIdx); } this.scrollTop = scrollTop; }, 50), // 使用50ms的节流以减少频繁刷新 }, mounted() { // 初始化数据 this.totalItems = Array.from({ length: 1000 }, (_, i) => ({ id: i + 1, text: `Item ${i + 1}`, })); }, }; // 节流函数:限制函数在指定时间内只能执行一次 function throttle(func, delay) { let last = 0; return function (...args) { const now = new Date().getTime(); if (now - last > delay) { last = now; return func.apply(this, args); } }; } </script> <style> .container { height: 100vh; } .scroll-view { height: 100%; } .item { height: 60px; display: flex; align-items: center; justify-content: center; border-bottom: 1px solid #ddd; } </style>
网友回复
有没有开源的solo agent一句话描述就能开发直接运行的前后端应用源代码?
订单支付过程中部分商品库存不足如何处理?
python如何开发一个自定义域名后缀的邮箱系统及登录发送邮件管理web页面?
有没有开源的项目将图片视频声音文字转场特效编排自动生成剪映草稿json文件?
有没有摄像头捕获眼球转动操作鼠标的开源代码?
localstorage如何生成自增的键值对进行增删改查?
python有没有将python脚本与python运行环境一键打包成exe的代码?
nodejs如何执行浏览器中运行的js代码?
iframe中如何阻止其他域名网页的打开或跳转?
webrtc如何实现多人音频电话会议?