vue3 虚拟长列表实现demo

<template>
    <div class="box" ref="box" :style="{height:contentHeight+'px'}" @scroll="scrollListener">
        <div class="content" :style="{position:'relative',height:showBoxHeight+'px'}">
            <div class="position" :style="{position:'absolute',top:top+'px'}">
                <div class="list" v-for="(item,index) in showList" :key="index" :style="{
                    height:itemHeight+'px',
                    lineHeight:itemHeight+'px'}">
                    {{ item }}
                </div>
            </div>
        </div>
    </div>
</template>
<script setup>
import { computed, onMounted, ref } from 'vue';
    onMounted(()=>{
        getList()
        scrollListener()
    })
    const scrollTop=ref(0)//获取距离顶部距离
    const showNum=ref(0)  // 可展示个数
    const box=ref(null)    //大盒子节点    
    const top=ref(0)        //距离顶部距离
    const endIndex=ref(null) //结束位置
    const startIndex=ref(0)  //第一个节点位置
    const contentHeight=600  //内容高度
    const itemHeight=30      //每个节点高度
    //构造虚拟列表
    const list=ref([])
    const showList=ref([])
    const getList=()=>{
      list.value=  Array.from({length:100000}).map((item,index)=>{
               return `第${index+1}条数据`
        })
    }
    const showBoxHeight=computed(()=>{
        return itemHeight*100000
    })
    const scrollListener=()=>{
        //获取距离顶部位置
         scrollTop.value=box.value.scrollTop
         console.log(scrollTop.value,'距离顶部距离');
         //展示数据个数
         showNum.value=Math.ceil(contentHeight/itemHeight)
         console.log(scrollTop.value,'展示数据个数');
         //起点位置
         startIndex.value=Math.floor(scrollTop.value/itemHeight)
         console.log(scrollTop.value,'起点位置');
         endIndex.value=startIndex.value+showNum.value
         console.log(endIndex.value,'起点位置');
        showList.value=list.value.slice(startIndex.value, endIndex.value)
        console.log(showList.value,'起点位置');
        top.value=startIndex.value*itemHeight
        console.log(scrollTop.value,'起点位置');
    }

</script>
<style lang="scss" scoped>
.box{
    width: 500px; 
    box-shadow: 2px 2px 2px rgb(114, 113, 113);
    overflow-y: auto;
}

</style> 

 

posted @ 2025-04-12 13:31  bingxiaoxiao  阅读(48)  评论(0)    收藏  举报