大家好,我是前端架构师,关注微信公众号【程序员大卫】领取免费前端精品资料。
这是虚拟列表系列的第二篇文章,这次将为虚拟列表添加缓冲区。如果你还没看过上一篇内容,可以先点击这里了解:【全网最通俗易懂】虚拟列表:渲染十万条数据不卡顿(附demo和源码)。
本文主要讲解如何为虚拟列表添加
缓冲区的功能。下一篇将是虚拟列表系列的终章,我们将探讨如何实现不定高虚拟列表、动态监听高度等更高级的技术。
背景
为什么虚拟列表需要添加缓冲区?
这是因为在快速上下滚动时,可能会出现部分内容显示不全的情况。缓冲区的存在可以有效避免这一问题。
实现方案
我们假设每项的高度固定为 100px,同时缓冲区在可视区域上下各有 2 项。
以下是两种情况的处理逻辑:
情况一:滚动未超过缓冲区范围
假设当前的滚动高度为 240px,此时滚动的位置尚未超出缓冲区范围,因此无需设置渲染区域的偏移量(offset)。渲染效果如下:
情况二:滚动超过缓冲区范围
假设当前滚动高度为 440px,下面对两种渲染效果进行对比:
1.普通列表的滚动效果
正常情况下,滚动至 440px 时,视觉效果如下:
2.未设置偏移量的缓冲区滚动效果
如果不设置偏移量,渲染效果会显得不自然,与普通滚动效果不一致:
为了使视觉效果与普通滚动一致,我们需要为渲染区域设置 200px 的偏移量。调整后的效果如下:
核心代码实现
结合上文的分析,我们可以看出:与未设置缓冲区的虚拟列表相比,添加缓冲区后主要差异在于 起始索引 和 结束索引 的计算。其余逻辑保持不变。
以下是实现代码:
// 计算当前可视范围的顶部索引
const topIndex = computed(() => Math.floor(scrollTop.value / props.itemSize));
// 当前滚动位置对应的起始索引
const startIndex = computed(() =>
Math.max(0, topIndex.value - props.bufferCount)
);
// 当前滚动位置对应的结束索引,基于起始索引和可视数量
const endIndex = computed(() =>
Math.min(
totalItemCount.value - 1,
topIndex.value + visibleCount.value + props.bufferCount
)
);
源码
最后
点赞👍 + 关注➕ + 收藏❤️ = 学会了🎉。
更多优质内容关注公众号,@前端大卫。