vue实现虚拟滚动(面试题:后端给你十万条数据,你怎么处理?)

发布时间 2024-01-08 16:48:30作者: 李昂唐
<template>
  <div class="viewport" @scroll="scroll"> 
    <div class="list-phantom" :style="{height: totalHeight+'px'}"></div> 
    <div class="list-area" :style="{transform: `translate3d(0,${startOffset}px,0)`}"> 
      <div v-for="item in viewData" :key="item" class="list-item" :style="{height: height+'px',lineHeight: height+'px'}">{{item}}</div>
    </div>
</div>
</template>

<script>
export default {
  data(){
    return {
      list: [],
      height: 100,
      startIndex: 0,
      scrollTop: 0
    }
  },
  created(){
    for (let i = 0; i < 1000; i++) {
      this.list.push(i);
    }
    this.totalHeight = this.list.length * this.height
  },
  computed: {
    endIndex(){
      return this.startIndex + 10
    },
    viewData(){
      return this.list.slice(this.startIndex,this.endIndex)
    },
    startOffset(){
      return this.startIndex*this.height
    }
  },
  methods: {
    scroll(e){
      this.scrollTop = e.target.scrollTop
      this.startIndex = Math.floor(this.scrollTop / this.height)
    }
  }
}
</script>

<style>
.viewport {
  height: 100vh;
  overflow: scroll;
  position: relative;
}

.list-phantom {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
}

.list-item {
  color: #555;
  text-align: center;
  box-sizing: border-box;
  border-bottom: 1px solid #999;
}
</style>