简单解决前端虚拟列表问题

67 阅读1分钟

主要步骤:

  1. 模拟3万条数据放入contactList中,截取前10条放入reallyShowContactList展现到页面
  2. 添加@wheel滚动事件
  3. 获取容器的高度并计算出要展示的数据条数(初始化10条,计算出的条数最好也是10条)
  4. 用一个wheelHeight=0的变量来保存滚动的高度
  5. 计算滚动一次显示几条信息,建议和初始化的一样
  <div class="contact-content" id='contactContent' @wheel='scrollHandler'>
    <div class='contact-item' v-for="(item, index) in reallyShowContactList" :key='index'>
      {{ item.index }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      contactList: [],
      reallyShowContactList: [],
      wheelHeight: 0
    }
  },
  mounted() {
    this.contactList = Array(30000).fill({}).map((item, index) => ({
      index: index
    }))
    // 1
    this.reallyShowContactList = this.contactList.slice(0, 10);
  },
  methods: {
    scrollHandler(e) {
      e.preventDefault();
      // 获取列表容器的高度  2
      const contentBoxHeight = document.getElementById('contactContent').offsetHeight;
      // 计算出一页展示的数量  3
      const showCount = Math.ceil(contentBoxHeight / 20);
      // 滚动高度  4
      this.wheelHeight += e.deltaY;
      
      if (this.wheelHeight < 0 || !this.reallyShowContactList.length) {
        this.wheelHeight = 0;
        return;
      }
      // 5
      let start = Math.floor(this.wheelHeight / 10);
      start = start < 0 ? 0 : start;
      this.reallyShowContactList = this.contactList.slice(start, start + showCount);
    }
  }
}
</script>

<style scoped lang="scss">
.contact-content {
  background-color: beige;
  height: 200px;
}
.contact-item {
  height: 20px;
  line-height: 20px;
  border-bottom: 1px solid #ccc;
  &:last-child {
    border-bottom: none;
  }
  text-align: center;
}
</style>