如下代码:
<template>
<div>
<div class="home" :style="{height:`${contentheight}px`}" @scroll="scroll">
<div :style="{'height':`${itemheight*list.length}px`,'position':'relative'}">
<div :style="{'position':'absolute','top':`${top}px`}">
<div v-for="(item,index) in showlist" :key="index" class="item">{{item}}</div>
</div>
</div>
</div>
{{ scrollTop }}
</div>
</template>
<script>
export default {
name: "FivthXunilist",
data() {
return {
list: [], //后端返回的1000条数据【模拟】
scrollTop: 0, //卷起的高度
showlist: [], //可视区的数据列表
contentheight: 300, //可视区总高300
itemheight: 30, //每条60,每页5个数据
showNum: 0, //每页展示个数
startindex: 0, //可视区第一条数据的索引
enindex: 0, //最后一条数据的索引
top:0,//偏移量
};
},
mounted() {
this.getlist();
this.scroll();
},
methods: {
getlist() {
for (let i = 0; i <= 1000; i++) {
this.list.push(`我是第${i}条数据`);
}
},
getshowlist() {
this.showNum = Math.ceil(this.contentheight / this.itemheight);//每页展示条数
this.startindex = Math.floor(this.scrollTop / this.itemheight);//开始数据的索引
this.enindex = this.startindex + this.showNum;//结束的索引
this.showlist = this.list.slice(this.startindex,this.enindex);
const offsetY = this.scrollTop - (this.scrollTop%this.itemheight);
this.top = offsetY;
console.log(this.showlist,this.top,'=====this.showlist')
},
scroll() {
this.scrollTop = document.querySelector(".home").scrollTop;
this.getshowlist();
},
},
};
</script>
<style lang="scss" scoped>
.home {
width: 200px;
border: 1px solid #000;
margin: 0;
padding: 0;
overflow: auto;
}
// ul,
// li {
// margin: 0;
// padding: 0;
// }
.item {
width: 100%;
height: 25px;
background: yellow;
border-bottom: 1px solid red;
}
</style>
后端返回的长列表数据,前端采用虚拟列表方案
设置可视区固定高度,设置overflow属性,使其可滚动
计算每条数据的宽度, 一屏可视区可以展示的数据条数
监听滚动, 计算卷上去多少条数, 那么可计算出可视区的第一条数据的索引是多少
根据每条数据的高度, 计算最后一条索引是多少
在后端返回的长列表数据中截取可视区要展示的数据
计算起始索引对应的数据在整个列表中偏移的位置并设置到列表上