美文网首页
vue 实现简单虚拟列表

vue 实现简单虚拟列表

作者: wxw_威 | 来源:发表于2023-08-07 15:18 被阅读0次

    当后端一次性返回10w条数据,前端页面如果一次渲染的话,会有延迟,或者页面直接卡死,所以需要用到虚拟列表,每次加载可视区域内的数据,滚动页面的时候,更新数据。
    废话不多说,直接上代码~
    像这样,只更新可视区域的数据:


    1691479026988.png

    1、cell高度固定

    <template>
      <div class="base-layout">
        <div ref="scrollRef" class="scroll-view" @scroll="handleScroll">
          <div class="scroll-content" :style="{ height: contentHeight + 'px' }">
            <div class="content-list" :style="{ paddingTop: topValue + 'px' }">
              <p v-for="item in list" :key="item.id">{{ item.id }}</p>
            </div>
          </div>
        </div>
      </div>
    </template> 
    <script lang="ts" setup>
      import { computed, onMounted, reactive, ref } from 'vue';
      
      let allList = ref(<any>[])  // 所有数据
      let contentHeight = ref(0)  // 根据数据,计算scrolleViwe 的内部区域高度,为了显示滚动的可视区域
      let topValue = ref(0) // 滚动条滚动距离顶部的高度
      let startIndex = ref(0) // 要截取所有数据的起始下标
      let visibleCount = ref(0)  // 可视区域内的cell数量
      const itemHeight = ref(30)  // cell 的高度
      const scrollRef = ref()
    
      // 可视区域内要显示的数组
      let list = computed(() => {
        let arr = allList.value.slice(startIndex.value, startIndex.value + visibleCount.value)
        return arr
      })
    
      onMounted(() => {
        // scrollRef.value.offsetHeight: 获取可视窗口的高度
        // 根据cell固定高度,计算可视区域内cell的数量
        visibleCount.value = Math.ceil(scrollRef.value.offsetHeight / itemHeight.value)
    
        getAllList()
      })
    
      function getAllList() {
        for(let i = 1; i <= 100000; i++) {
          allList.value.push({ id: i })
        }
        // 计算内容区域高度
        contentHeight.value = allList.value.length * 30
      }
      function handleScroll(val: { target: { scrollTop: number; }; }) {
        // 获取滚动条距离顶部的距离
        topValue.value = val.target.scrollTop
        // 计算起始下标
        startIndex.value = Math.floor(topValue.value / itemHeight.value) 
      }
    
    </script>
    
    <style lang="scss" scoped>
    .base-layout {
      padding: 8px 20px;
      .scroll-view {
        background-color: papayawhip;
        border: 1px solid orange;
        box-sizing: border-box;
        height: 300px;
        width: 300px;
        overflow-y: auto;
      }
      p {
        height: 30px;
        line-height: 30px;
        margin: 0;
        border-bottom: 1px solid gainsboro;
        box-sizing: border-box;
      }
    }
    </style>
    

    相关文章

      网友评论

          本文标题:vue 实现简单虚拟列表

          本文链接:https://www.haomeiwen.com/subject/zzegpdtx.html