持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情
懒加载
经常会遇到这样的问题,如果后端给我们20000条数据,我们要怎么加载它,直接全部渲染到dom上?不,这样不行,这样我的页面会卡死,性能影响太严重,我们可以只加载此时的视图范围内的数据
实现
- 首先需要一个数组,里面放20000条数据
- 每次只加载视图范围内的数据,我们就需要一个开始的下标,一个结束的下标,用来确认此时应该展示的数据范围
- 还需要一个值用来确认此时的滚动的top值,确定此时的试图在哪里
一个节点,用来展示滚动条,里面放一个撑起滚动条的节点,他的高度为数组的长度 * 25(25为自定义), 另一个节点放需要渲染的dom
HTML结构如下
<div class="listContext" @scroll="listScroll">
<div ref="scrollHeight"></div>
<div class="warp">
<div>
//需要熏染的节点在这里
</div>
</div>
</div>
CSS
.listContext {
height: 200px;
overflow: scroll;
position: relative;
}
.warp {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
逻辑
- 当我们滚动的时候,触发滚动事件,然后拿到滚动到上面的top
- 确定此时的top所对应的开始的下标是多少:stateIndex = ScrollTop / 25(渲染节点的高度)
- endIndex = stateIndex + 此时试图需要渲染的数量
- 这样我们就可以截取数组,拿到需要渲染的数组,通过v-for,渲染到dom中
- 但是还需要把此时的warp向下移动,移动stateIndex * 25 的高度,因为我们向下滚动了这么多,所以需要移动
逻辑实现
创建10000条数据
for (let i = 0; i < 1000; i++) {
listArray.push(i);
}
滚动事件,确认stateIndex,endIndex,scrollOffset
const listScroll = (e) => {
stateIndex.value = Math.ceil(e.target.scrollTop / 25);
endIndex.value = 200 / 25 + stateIndex.value;
scrollOffset.value = stateIndex.value * 25;
};
监听stateIndex,endIndex
watchEffect(() => {
showArray.value = listArray.slice(stateIndex.value, endIndex.value);
})
onMounted(() => {
//确认滚动条高度
scrollHeight.value.style.height = listArray.length * 25 + "px";
});
HTML
<div class="listContext" @scroll="listScroll">
<div ref="scrollHeight"></div>
<div :style="{ transform: `translateY(${scrollOffset}px)` }" class="warp">
<div v-for="item in showArray" :key="item" class="item">
{{ item }}
</div>
</div>
</div>
此时的就可以展示我们需要展示的内容了
我们可以看到,一直都是只渲染8条数据,极大的提高了性能
结束
今天面试了两家,感觉自己又行了,加油哇!