前言
在前端开发过程中,有时候会遇到一些不能使用分页来加载数据的情况,因此当我们需要渲染上十万条数据的时候,可能会造成渲染的卡顿,导致用户体验特别不好,那么对于这种情况我们该怎么去解决呢?这个时候就不得不提到虚拟列表。
看了大佬门写的虚拟列表实现方式感觉比较复杂,加了很多其他功能,比如节流什么的,于是乎自己手动鲁一个简单版的。
什么是虚拟列表
虚拟列表其实是按需显示的一种实现,即只对可见区域进行渲染,对非可见区域中的数据不渲染或部分渲染的技术,从而达到极高的渲染性能。假设有10万条记录需要同时渲染,我们屏幕的可见区域的高度为550px,而列表项的高度为55px,则此时我们在屏幕中最多只能看到10个列表项,那么在渲染的时候,我们只需加载可视区的那10条即可
完成效果
附上代码
<script setup lang="ts">
import { ref,reactive } from 'vue'
var arrList:Array<T> = []
for(let i=0;i<100;i++){
arrList.push({
img:'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-5d76cc72-d23e-4bb4-8d70-735f28e59f33/48f666a8-00c4-4600-ba17-eb846637084d.png?x-oss-process=image/resize,m_pad,h_178,w_178',
title:'虚拟列表',
content:'阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴',
id:i
})
}
function handleScroll() { //监听滚动条,设置padding-top、padding-bottom
window.addEventListener('scroll', () => {
let showSum = 10 //可视区显示的盒子个数
let listBoxHeight = 210 //每个盒子高度
let lengthSum = arrList.length //数据总数
let start = Math.floor(window.scrollY/listBoxHeight) //截取数据的开始位置
let end = start + showSum //截取数据的结束位置
//设置pandding
style.top = listBoxHeight * start
style.bottom = listBoxHeight * (lengthSum - end)
//截取数据
reList.value = reactive(arrList.slice(start,end))
});
}
handleScroll()
let style = reactive({top:0,bottom:0})
let reList = reactive({value:arrList.slice(0,10)})
</script>
<template>
<div ref="content" class="content" :style="{'padding-top':style.top+'px','padding-bottom':style.bottom+'px'}">
<div v-for="(item,index) in reList.value" :key="index" :id="item.id" class="re-list">
<img :src="item.img" alt="">
<div class="right">
<h3>{{item.title}}</h3>
<p>{{item.content}}</p>
</div>
</div>
</div>
</template>
<style lang="less" scoped>
.content{
.re-list {
height: 210px;
color: #888;
display: flex;
flex-direction: row;
border-bottom: 2px solid #999;
.empty{
width: 100%;
}
.right{
}
}
}
</style>