template
<template>
<div id="g" @scroll="handleScroll">
<div :style="{ height: top + 'px' }"></div>
<div class="item" v-for="item in list" :key="item">
{{ item }}
</div>
<div :style="{ height: bot + 'px' }"></div>
</div>
</template>
script
import { ref } from 'vue'
export default {
name: 'App',
setup() {
const total = 2000 // 数据总数
const h = 50 // 数据容器高
const h2 = 500 // 容器高
const h3 = total * h
const top = ref(0)
const bot = ref(h3 - h2)
const data = []
for (let i = 0; i < total; i++) {
data.push(i)
}
const list = ref(data.slice(0, Math.ceil(h2 / h)))
const handleScroll = (event) => {
const { scrollTop } = event.target
const begin = Math.floor(scrollTop / h)
const end = Math.ceil((scrollTop + h2) / h)
top.value = begin * h
bot.value = h3 - (end - begin) * h - top.value
list.value = data.slice(begin, end)
}
return {
h,
h2,
top,
bot,
list,
handleScroll,
}
},
}
style
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
background-color: orange;
}
#g {
width: 300px;
height: v-bind(h2 + 'px');
background-color: #fff;
overflow-y: auto;
}
.item {
box-sizing: border-box;
height: v-bind(h + 'px');
border-bottom: 1px solid #eee;
}