【Vue3】实现动态高度的虚拟滚动列表

什么是虚拟滚动列表

虚拟滚动列表是一种优化长列表渲染性能的技术,通过只渲染可视区域内的列表项,减少‌DOM的渲染数量,从而提高页面滚动的流畅性。

核心原理

在滚动时,只渲染可视区域内的列表项,而不是一次性渲染所有列表项。通过计算可视区域的起始索引和结束索引,动态渲染该范围内的列表项。当用户滚动时,根据滚动位置动态更新可视区域内的列表项,从而实现虚拟滚动的效果。

图例:

【Vue3】实现动态高度的虚拟滚动列表_第1张图片

实现思路

为了实现虚拟滚动列表,需要设计三个盒子(可视区盒子、列表容器、列表项容器)

  1. 可视区盒子,控制列表展示的区域,超出滚动;
  2. 列表容器,包裹所有列表项的盒子,高度为真实列表的高度;
  3. 列表项容器,每个列表项外的盒子,用于动态定位展示列表项;

解释:监听1中盒子的滚动事件,在滚动的时候通过事件对象中的scrollTop动态计算对应展示区列表项的开始索引和结束索引,通过列表项的高度计算出对应列表项的偏移量,更新展示区域的列表项;

代码实现

这里需要计算所有列表项外包裹的盒子的高度以及每一项列表偏移量,但是由于我们要渲染的列表项每一项的高度都是不等长的,所以我们只有在对应列表项DOM渲染完成之后才知道每一项的真实高度,然后我们需要维护一个所有列表项对应的高度和偏移量的map数据,用于更新列表,每次在真实的列表项挂在之后动态去更新这个map数据,再以此为模板动态更新包裹的盒子的高度;

list-item容器代码


此处使用ResizeObserver这个api来监听列表项dom尺寸的改变,用于更新我们维护的列表项map,但是这个api在低版本浏览器会有兼容性问题,导致白屏报错,可安装resize-observer-polyfill兼容低版本浏览器;

list容器代码


list组件参数
  • props:定义组件的属性,包括是否隐藏滚动条、容器高度、宽度、每项预估高度、总项数、数据列表和缓冲区大小。

  • ref:定义了一些响应式变量,如virtualWrapshowItemListtotalEstimatedHeightscrollOffset

  • watch:监听props.data的变化,当数据变化时重新计算可视区域内的项。

  • sizeChangeHandle:处理列表项大小变化的事件,更新元数据。

  • measuredData:存储已测量项的元数据,包括大小和偏移量。

  • getCurrentChildren:根据滚动位置计算当前需要渲染的项,并更新showItemList

  • getRangeToRender:计算需要渲染的项的起始和结束索引。

  • getStartIndex:根据滚动位置计算可视区域开始的项的索引。

  • getItemMetaData:获取指定索引项的元数据,如果未计算过则进行计算。

  • getEndIndex:根据起始索引和缓冲区大小计算可视区域结束的项的索引。

  • estimatedHeight:计算总高度,包括已测量项和未测量项。

  • scrollHandle:处理滚动事件,更新滚动位置并重新计算可视区域内的项。

  • onMounted:组件挂载后,初始化可视区域内的项。

应用实现






你可能感兴趣的:(Vue3,园游会,技术改造,前端,javascript,vue.js)