将下面代码复制一份到自己的项目中 

<template>
    <div class="scrollParent" ref="scrollContent" @scroll="handleScroll">
        <div :style="blankFillStyle">
            <div v-for="item,index in showDataList" :key="index">
                <slot :everyVirtual="item"></slot>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    props:["oneHeight","virtualList"],
    data () {
        return {
            contentSize:"", //可视区域可以展示多少条数据
            startIndex:0, //记录当前滚动的第一个元素的索引
            currentScroll:0,  //记录当前滚动的距离
        }
    },
    methods:{
        // 获取可视区域可以展示多少条
        getContentSize(){
            // 两次取反可以获取到整数部分
            this.contentSize = ~~(this.$refs.scrollContent.offsetHeight / this.oneHeight) + 2;
        },
        // 监听滚动条
        handleScroll(){
            // 持续滚动  减少变量重新赋值  优化处理 只有在到下一个元素节点的时候才会重新给this.statrIndex赋值  避免和this.startIndex相关联的数据再次计算
            this.currentScroll = this.$refs.scrollContent.scrollTop;
            let currentIndex = ~~(this.$refs.scrollContent.scrollTop/this.oneHeight);
            if(this.startIndex == currentIndex){
                return
            }
            this.startIndex = currentIndex;
            if((this.startIndex + this.contentSize - 1)>this.virtualList.length-1){ //说明到达底部了
                this.$emit("scrollEnd")
            }
        }
    },
    activated(){
        this.$nextTick(()=>{
            this.$refs.scrollContent.scrollTop = this.currentScroll;
        })
    },
    computed:{
        endIndex(){ //获取最后一个元素的索引
            let endIndex = this.startIndex + this.contentSize*2;
            if(endIndex>this.virtualList.length-1){
                endIndex = this.virtualList.length-1
            }
            return endIndex;
        },
        showDataList(){
            let startIndex = 0;
            if(this.startIndex<=this.contentSize){
                startIndex = 0;
            }else{
                startIndex = this.startIndex - this.contentSize;
            }
            return this.virtualList.slice(startIndex,this.endIndex);
        },
        blankFillStyle(){
            let startIndex = 0;
            if(this.startIndex<=this.contentSize){
                startIndex = 0;
            }else{
                startIndex = this.startIndex - this.contentSize;
            }
            return{
                paddingTop:startIndex * this.oneHeight + "px",
                paddingBottom:(this.virtualList.length - this.endIndex) * this.oneHeight +"px"
            }
        }
    },
    mounted(){
        window.onresize = this.getContentSize();
        window.orientationchange = this.getContentSize();
    }
}
</script>

<style scoped>
    .scrollParent{
        height: 100%;
        width: 100%;
        overflow-y: auto;
    }
</style>

引入模块,调用模块

 <virtualScroll v-if="virtualList && virtualList.length"
         :oneHeight='40' 
         :virtualList='virtualList' 
         @scrollEnd='scrollEnd'
         v-slot:default="virtual">
        <div class="everyVirtual">{{virtual.everyVirtual}}</div>
 </virtualScroll>



oneHeight  每一个的高度
virtualList    请求拿到的数据列表
scrollEnd    滚动条滚动到底部的回调
<div class="everyVirtual">{{virtual.everyVirtual}}</div>    插槽、书写自己的每一个样式

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐