vue虚拟列表简单易懂

602 阅读1分钟

前言

在前端开发过程中,有时候会遇到一些不能使用分页来加载数据的情况,因此当我们需要渲染上十万条数据的时候,可能会造成渲染的卡顿,导致用户体验特别不好,那么对于这种情况我们该怎么去解决呢?这个时候就不得不提到虚拟列表。

看了大佬门写的虚拟列表实现方式感觉比较复杂,加了很多其他功能,比如节流什么的,于是乎自己手动鲁一个简单版的。

什么是虚拟列表

虚拟列表其实是按需显示的一种实现,即只对可见区域进行渲染,对非可见区域中的数据不渲染或部分渲染的技术,从而达到极高的渲染性能。假设有10万条记录需要同时渲染,我们屏幕的可见区域的高度为550px,而列表项的高度为55px,则此时我们在屏幕中最多只能看到10个列表项,那么在渲染的时候,我们只需加载可视区的那10条即可

完成效果

GIF.gif

附上代码

<script setup lang="ts">
import { ref,reactive } from 'vue'
var arrList:Array<T>  = []
for(let i=0;i<100;i++){
  arrList.push({
    img:'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-5d76cc72-d23e-4bb4-8d70-735f28e59f33/48f666a8-00c4-4600-ba17-eb846637084d.png?x-oss-process=image/resize,m_pad,h_178,w_178',
    title:'虚拟列表',
    content:'阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴阿巴',
    id:i
  })
}

function handleScroll() { //监听滚动条,设置padding-top、padding-bottom
    window.addEventListener('scroll', () => {
        let showSum = 10 //可视区显示的盒子个数
        let listBoxHeight = 210 //每个盒子高度
        let lengthSum = arrList.length //数据总数
        let start = Math.floor(window.scrollY/listBoxHeight) //截取数据的开始位置
        let end = start + showSum //截取数据的结束位置

        //设置pandding
        style.top = listBoxHeight * start
        style.bottom = listBoxHeight * (lengthSum - end)
        //截取数据
        reList.value =  reactive(arrList.slice(start,end))
    });
}
handleScroll()

let style = reactive({top:0,bottom:0})

let reList = reactive({value:arrList.slice(0,10)})
</script>

<template>
  <div  ref="content" class="content" :style="{'padding-top':style.top+'px','padding-bottom':style.bottom+'px'}">
    <div v-for="(item,index) in reList.value" :key="index" :id="item.id" class="re-list">
      <img :src="item.img" alt="">
      <div class="right">
        <h3>{{item.title}}</h3>
        <p>{{item.content}}</p>
      </div>
    </div>
  </div>
</template>

<style lang="less" scoped>
.content{
  .re-list {
    height: 210px;
    color: #888;
    display: flex;
    flex-direction: row;
    border-bottom: 2px solid #999;
  .empty{
    width: 100%;
  }
  .right{
  }
}
}
</style>