主要用到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.lengthconst visibleData = computed(() => {let startIndex = offsetY.value / itemHeightlet endIndex = startIndex + rowCountreturn rowData.slice(startIndex, endIndex)
})const handleScroll = function(e) {offsetY.value = e.target.scrollTop;
}
</script>
<style scoped>
.virtual-table-content {height: 100%;
}
</style>