背景:页面需要做动态列表数据展示,一次性请求大量数据会造成页面卡顿,用户体验很糟糕。为了提升页面性能想到了主流的两种方案:1.虚拟滚动、2.滚动到底部时请求接口获取数据。
方案一:虚拟滚动:
原理:
虚拟滚动的基本原理是只渲染可视区域内的列表项,而不是全部数据。当用户滚动页面时,系统会动态计算当前可视区域内的列表项,并只渲染这部分数据。
好处:
无论列表有多长,都只需要维护一定数量的DOM节点,从而大大提高了性能。具体来说,系统会计算出列表的总高度(totalHeight),并在触发滚动事件时,根据scrollTop值不断更新startIndex和endIndex,以此从列表数据中截取对应元素进行渲染,实现虚拟滚动的效果。
实现:
掘金上面有一篇文章讲的很好,这里请大家直接看掘金的这篇文章就行了。 链接:juejin.cn/post/723285…
方案二:滚动加载(懒加载):
原理:
通过监听滚动事件来判断是否滚动到了底部,并在达到底部时发起请求。
好处:
用户需要查看更多内容时,才会发起请求加载数据,这样可以节省带宽和服务器资源,滚动监听而不是一次性加载所有数据,可以显著减少初始加载时的数据量,从而加快页面加载速度,提高用户体验
简单的示例:
<template>
<div class="scroll-container" @scroll="handleScroll">
<!-- 内容 -->
<div v-for="item in items" :key="item.id">{{ item.content }}</div>
<!-- 加载提示 -->
<div v-if="isLoading">加载中...</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [], // 数据列表
isLoading: false, // 是否正在加载
page: 1, // 当前页数
pageSize: 10, // 每页数据量
hasMore: true, // 是否有更多数据
};
},
methods: {
handleScroll(event) {
const { scrollTop, scrollHeight, clientHeight } = event.target;
// 当滚动到底部且没有正在进行的请求时加载更多数据
if (scrollTop + clientHeight >= scrollHeight && !this.isLoading && this.hasMore) {
this.loadMoreData();
}
},
loadMoreData() {
this.isLoading = true;
// 模拟发起请求获取数据
setTimeout(() => {
const moreItems = Array.from({ length: this.pageSize }, (_, i) => ({
id: this.items.length + i,
content: `Item ${this.items.length + i}`,
}));
this.items = [...this.items, ...moreItems];
this.page += 1;
// 模拟检查是否还有更多数据
if (this.items.length >= 50) {
this.hasMore = false;
}
this.isLoading = false;
}, 1000);
},
},
mounted() {
// 初始加载数据
this.loadMoreData();
},
};
</script>
<style>
.scroll-container {
height: 300px; /* 设置一个固定高度 */
overflow-y: auto; /* 开启滚动 */
}
</style>
在这个例子中,.scroll-container 是一个具有固定高度并且内容可滚动的容器。当用户滚动并且容器滚动到底部时,handleScroll 方法会被触发。如果没有更多数据加载并且不在加载状态,则会调用 loadMoreData 方法发起数据请求。
注意:实际应用中需要将 loadMoreData 方法中的模拟请求替换为实际的数据请求逻辑,并在请求成功后更新数据列表 items。同时,可能需要根据实际的后端接口和数据分页逻辑调整请求参数和处理逻辑。