虚拟列表
主要用到scrollTop、overflow:hidden、position:absolute
- 固定可视区域的列表高度和原始数据的总高度
- 获取scrollTop
- 根据scrollTop滚动条数,重新拿原数组中的数据
<template>
<div class="virtual-table" :style="{
width: '600px',
height: containerHeight + 'px',
overflow: 'auto',
}" @scroll="handleScroll">
<div class="virtual-table-content" :style="{
height: totalHeight + 'px',
position: 'relative',
}" >
<div v-for="item in visibleData"
:key="item.id"
:style="{
height: itemHeight + 'px',
position: 'absolute',
top: (item.id * itemHeight) + 'px',
left: 0,
}"
class="virtual-table-item">
{{ item.name }} - {{ item.value }}
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const rowData = Array.from({ length: 10000 }, (_, i) => ({
id: i,
name: `Item ${i + 1}`,
value: Math.floor(Math.random() * 1000),
}));
const containerHeight = 400
const itemHeight = 50
const rowCount = Math.floor(containerHeight / itemHeight) + 1
let offsetY = ref(0)
const totalHeight = itemHeight * rowData.length
const visibleData = computed(() => {
let startIndex = offsetY.value / itemHeight
let endIndex = startIndex + rowCount
return rowData.slice(startIndex, endIndex)
})
const handleScroll = function(e) {
offsetY.value = e.target.scrollTop;
}
</script>
<style scoped>
.virtual-table-content {
height: 100%;
}
</style>
浙公网安备 33010602011771号