同时渲染大量数据优化-虚拟列表
在网页里面,在某个可视容器内(某个div)一次性渲染所有数据,其实用户也只能看见一部分数据,其余得通过滚动来查看;
那么我们可以只渲染可见部分数据,不可见部分数据不渲染,通过上下padding来进行占位使其可以滚动;
滚动得时候不断计算可所需展示数据的开始下标和结束下标来截取可视数据;
<!doctype html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.container {
width: 300px;
height: 600px;
overflow: auto;
border: 1px solid;
margin: 100px auto;
}
.item {
height: 29px;
line-height: 30px;
border-bottom: 1px solid #aaa;
padding-left: 20px;
}
</style>
</head>
<body>
<div id="app">
<div class="container" ref="container">
<div class="scroll-wrapper"
:style="{'paddingTop':this.paddingTop + 'px','paddingBottom': this.paddingBottom + 'px'}">
<div v-for="(item, index) in datas" :key="index" class="item">{{item}}</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12"></script>
<script>
new Vue({
el: '#app',
data: {
list: [],//总数居
startIndex: 0,//可见数据开始下标
endIndex: 60,//可见数据结束下标
paddingTop: 0,//上padding
paddingBottom: 0,//下padding
allHeight: 0//总高度
},
computed: {
// 可见数据
datas() {
return this.list.slice(this.startIndex, this.endIndex);
},
// 数据总条数
numbers(){
return this.list.length;
}
},
watch: {
list(val) {//根据总数据计算总高度和初始下padding
const valLen = val.length;
this.allHeight = valLen * 30;
this.paddingBottom = this.allHeight - this.datas.length * 30;
}
},
mounted() {
const container = this.$refs.container;
// 添加滚动事件
container.addEventListener('scroll', () => {//计算上下padding和数据开始结束下标
const top = container.scrollTop;//获取滚动高度
this.startIndex = Math.floor(top / 30);//获取数据开始下标,例如,top为100时,startIndex为3,表示第一二三个数据已经不在可视区域,从第四个开始显示
this.endIndex = this.startIndex + 60;//数据结束下标
this.paddingTop = top;//滚动距离为上padding
// 结束下标大于等于数据个数时表示滑动到了底部,下padding设置为0
if (this.endIndex >= this.numbers) {
this.endIndex=this.numbers;
this.paddingBottom = 0
return
}
console.log(this.endIndex)
//下padding等于总高度-上padding-可是区域高度
this.paddingBottom = this.allHeight - 600 - this.paddingTop;
})
// 添加数据
let arr = new Array(100000).fill(0);
arr = arr.map((item, index) => {
return index;
})
this.list = arr;
}
})
</script>
</body>
</html>
原文链接:https://blog.csdn.net/qq_30282133/article/details/112343569
分类:
vue
, javaScript
标签:
javaScript
, vue
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现