用 Vue 3 实现虚拟滚动容器

template

<template>
  <div id="g" @scroll="handleScroll">
    <div :style="{ height: top + 'px' }"></div>
    <div class="item" v-for="item in list" :key="item">
      {{ item }}
    </div>
    <div :style="{ height: bot + 'px' }"></div>
  </div>
</template>

script

import { ref } from 'vue'

export default {
  name: 'App',
  setup() {
    const total = 2000 // 数据总数
    const h = 50 // 数据容器高
    const h2 = 500 // 容器高
    const h3 = total * h
    const top = ref(0)
    const bot = ref(h3 - h2)

    const data = []
    for (let i = 0; i < total; i++) {
      data.push(i)
    }

    const list = ref(data.slice(0, Math.ceil(h2 / h)))

    const handleScroll = (event) => {
      const { scrollTop } = event.target
      const begin = Math.floor(scrollTop / h)
      const end = Math.ceil((scrollTop + h2) / h)

      top.value = begin * h
      bot.value = h3 - (end - begin) * h - top.value

      list.value = data.slice(begin, end)
    }

    return {
      h,
      h2,
      top,
      bot,
      list,
      handleScroll,
    }
  },
}

style

body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
  background-color: orange;
}

#g {
  width: 300px;
  height: v-bind(h2 + 'px');
  background-color: #fff;
  overflow-y: auto;
}

.item {
  box-sizing: border-box;
  height: v-bind(h + 'px');
  border-bottom: 1px solid #eee;
}
posted @ 2022-03-02 09:43  尹宇星_Kim  阅读(372)  评论(0编辑  收藏  举报