基于vue2.0前端多条数据实现虚拟列表

实现原理:

测试多条数据是随机的,后续可以自行从父组件传入子元素的高度和数组;源码如下:

<template>
    <!-- 可视区域的容器 -->
    <div ref="list" class="list-container" @scroll="scrollEvent($event)">
        <!-- 容器内的占位,高度为总列表高度,用于形成滚动条 -->
        <div class="scroll-area" :style="{ height: listHeight + 'px' }"></div>
        <!-- 为列表项的渲染区域 -->
        <div class="view-area" :style="{ transform: getTransform }">
            <div ref="items"
                class="list-item"
                v-for="item in visibleData"
                :key="item.key"
                :style="{ height: itemHeight + 'px',lineHeight: itemHeight + 'px' }"
            >{{ item.value }}</div>
        </div>
    </div>
</template>
<script>
export default {
    data(){
        return{
            itemHeight:200,
            listData:[],
            screenHeight:0,//可视区域高度
            startOffset:0,//偏移量
            start:0,//起始索引
            end:null,//结束索引
        }
    },
    beforeMount(){
        this.listData = new Array(100);
        // 生成随机整数并赋值给数组的每个元素
        for (let i = 0; i < this.listData.length; i++) {
            this.listData[i] = {value:Math.floor(Math.random() * 100),key:i};
        }
    },
    computed:{
        listHeight(){//列表总高度
            return this.listData.length * this.itemHeight;
        },
        visibleCount(){//可显示列表数据量
            return Math.ceil(this.screenHeight / this.itemHeight)
        },
        getTransform(){ //偏移量style
            return `translate3d(0,${this.startOffset}px,0)`;
        },
        visibleData(){//可视列表数据
            return this.listData.slice(this.start, Math.min(this.end,this.listData.length));
        }
    },
    mounted() {
        this.screenHeight = this.$el.clientHeight;
        this.start = 0;
        this.end = this.start + this.visibleCount;
    },
  methods: {
    scrollEvent() {
      let scrollTop = this.$refs.list.scrollTop;//当前滚动所在位置
      this.start = Math.floor(scrollTop / this.itemHeight);//当前开始索引
      this.end = this.start + this.visibleCount;//当前结束索引
      this.startOffset = scrollTop - (scrollTop % this.itemHeight);//此时的偏移量
    }
  }
}
</script>
<style scoped>
.list-container {
  height: 100%;
  overflow: auto;
  position: relative;
}

.scroll-area {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
}

.view-area {
  left: 0;
  right: 0;
  top: 0;
  position: absolute;
  text-align: center;
}

.list-item {
  padding: 10px;
  color: red
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值