1.需要确定展示的数据 这里自动生成1000条数据
//需要渲染的数据
let arrs = Array(1000)
.fill("")
.map((item, index) => ({
id: index,
content: `第${index + 1}条数据`,
}));
2.需要 展示的起始下标,结束下标 和每次渲染的节点数、单条数据的高度 并获取列表的dom
//需要展示单条数据的高度
let size = 60;
//需要展示的起始下标
let start = ref(0);
// 需要展示数据的结束下标
let end = ref(10);
//每次渲染的节点个数
let shownum = 10;
//获取列表dom
let container = ref(null);
3.分别计算出需要展示出来的数据、容器的高度、列表滚动的top值
//需要展示出来的数据
let showData = computed(() => {
return arrs.slice(start.value, end.value);
});
//容器的高度
let containerHeigth = computed(() => {
return size * shownum + "px";
});
//撑开容器内容高度的元素高度
let barHeigth = computed(() => {
return size * arrs.length + "px";
});
//列表项上滚动该表top值
let listTop = computed(() => {
return start.value * size + "px";
});
4.滚动事件
function handleScroll() {
//获取容器顶部滚动条的尺寸
const scrollTop = container.value.scrollTop;
//计算卷曲的数据条数,用计算的结果作为获取数据的起始和结束下标
//起始的下标就是卷去的数据条数,向下取整
start.value = Math.floor(scrollTop / size);
//结束下标就是起始下标加上需要展示的数据条数
end.value = start.value + shownum;
}
5.全部代码展示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
* {
margin: 0;
padding: 0;
}
.container {
overflow-y: scroll;
background-color: rgba(150, 150, 150, 0.5);
font-size: 20px;
font-weight: bold;
line-height: 60px;
width: 500px;
margin: 0 auto;
position: relative;
text-align: center;
}
.list {
position: absolute;
top: 0;
width: 100%;
}
</style>
<body>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<div id="app">
<div
class="container"
:style="{height:containerHeigth}"
@scroll="handleScroll"
ref="container"
>
<!-- 数据列表 -->
<div class="list" :style="{top:listTop}">
<!-- 列表项 -->
<div
v-for="item in showData"
:key="item.id"
:style="{height:size+'px'}"
>
{{item.content}}
</div>
<!-- 用于撑开高度的元素 -->
<div class="bar" :style="{height:barHeigth}"></div>
</div>
</div>
</div>
<script>
const { createApp, ref, computed } = Vue;
createApp({
setup() {
//需要展示单条数据的高度
let size = 60;
//需要展示的起始下标
let start = ref(0);
// 需要展示数据的结束下标
let end = ref(10);
//每次渲染的节点个数
let shownum = 10;
//获取列表dom
let container = ref(null);
//需要渲染的数据
let arrs = Array(1000)
.fill("")
.map((item, index) => ({
id: index,
content: `第${index + 1}条数据`,
}));
console.log(arrs);
//需要展示出来的数据
let showData = computed(() => {
return arrs.slice(start.value, end.value);
});
//容器的高度
let containerHeigth = computed(() => {
return size * shownum + "px";
});
//撑开容器内容高度的元素高度
let barHeigth = computed(() => {
return size * arrs.length + "px";
});
//列表项上滚动该表top值
let listTop = computed(() => {
return start.value * size + "px";
});
//容器的滚动事件
function handleScroll() {
//获取容器顶部滚动条的尺寸
const scrollTop = container.value.scrollTop;
//计算卷曲的数据条数,用计算的结果作为获取数据的起始和结束下标
//起始的下标就是卷去的数据条数,向下取整
start.value = Math.floor(scrollTop / size);
//结束下标就是起始下标加上需要展示的数据条数
end.value = start.value + shownum;
}
return {
size,
container,
showData,
containerHeigth,
barHeigth,
listTop,
handleScroll,
};
},
}).mount("#app");
</script>
</body>
</html>