Vue3.x实现虚拟列表

146 阅读1分钟

代码:

<template>
  <div class="test">
    <div ref="testRef" class="h-96 overflow-y-scroll">
      <ul :style="{ transform: `translateY(${translateY})` }">
        <li
          class="testBox h-16 flex items-center border-b-2 text-2xl"
          v-for="item in listData"
          :key="item.id"
        >
          {{ item.title }}
        </li>
      </ul>
    </div>
  </div>
</template>

<script setup lang="ts">
type testInfo = {
  id: number
  title: string
}

const data = ref<testInfo[]>([])

for (let i = 1; i < 99; i++) {
  data.value.push({
    id: i,
    title: `标题${i}号`
  })
}

const testRef = ref<any>()

const start = ref<number>(0)

const translateY = ref<number | string>(0)

const listData = computed(() => {
  return data.value.slice(start.value, start.value + 7)
})

onMounted(() => {
  testRef.value.addEventListener('scroll', (e: any) => {
    const { scrollTop } = e.target
    start.value = Math.floor(scrollTop / 64)
    translateY.value = scrollTop + 'px'
  })
})
</script>

解析:

  • 创建一个固定高度的父盒子,以及固定高度的列表
  • 将父盒子设置为溢出滚动,监听父盒子滚动的高度,计算出需要渲染的数据列表的初始索引值,结束索引值设置为初始索引值+1,+1是为了避免渲染时出现空白。
  • 将ul向上偏移,偏移量等于滚动高度,使ul和父盒子始终高度对齐。