/**
 *虚拟列表
 *
 */
<template>
  <div id="page">
    <div ref="vListContainer" id="vListContainer" class="page">
      <div class="item" v-for="(item, index) in vList" :key="index">{{item.value}}</div>
    </div>
  </div>
</template>

<script>
let list = [];
for (let i = 0; i < 100000; i++) {
  list.push({
    key: i,
    value: "list" + (i + 1)
  });
}
export default {
  name: "App",
  mounted() {
    this.initPostion();
    this.initScroll();
  },
  methods: {
    initPostion() {
      const HEIGHT = window.innerHeight;
      document.getElementById("vListContainer").style.height = `${list.length *
        100}px`;
      const IHEIGHT = 100;
      const total = Math.ceil(HEIGHT / IHEIGHT);
      this.start = 0;
      this.end = total;
      this.vList = list.slice(this.start, this.end);
    },
    initScroll() {
      window.addEventListener("scroll", this.scrollHandle);
    },
    scrollHandle(e) {
      var scrollTop =
        window.pageYOffset ||
        document.documentElement.scrollTop ||
        document.body.scrollTop;
      this.updateList(scrollTop);
    },
    updateList(top) {
      let s = Math.floor(top / 100);
      this.vList = list.slice(s, s + this.end);
      const container = document.getElementById("vListContainer");
      container.style.top = `${s * 100}px`;
      container.style.height = `${10000000 - s * 100}px`;
    }
  },
  data() {
    return {
      list,
      start: null,
      end: null,
      vList: []
    };
  }
};
</script>

<style scoped lang="less">
.item {
  height: 100px;
}
#vListContainer {
  position: relative;
}
</style>