什么是长列表

前端业务会涉及到数据量很大的且无法用分页进行加载的列表,我们一般叫做长列表,
完整的渲染长列表基本上很难达到业务的上的要求,非完整渲染长列表一般分为两种:
1.懒渲染:这个就是常见的无线滚动的,每次只渲染一部分(比如10条),等剩余部分滚到可见区域,就再渲染一部分。
2.可视区域渲染:只渲染可见部分,不可见部分不渲染。

虚拟列表就是采用的可视区渲染方式优化
 

虚拟列表实现原理 
 

虚拟列表(Virtual List),是一种长列表优化方案,是可视区渲染列表。其两个重要的概念:

  • 可滚动区域:假设有1000条数据,每个列表项的高度是30,那么可滚动的区域的高度就是1000*30。当用户改变列表的滚动条的当前滚动值的时候,会造成可见区域的内容的变更。
  • 可见区域:比如列表的高度是300,右侧有纵向滚动条可以滚动,那么视觉可见的区域就是可见区域。

实现原理

思路就是用vue的for循环渲染列表,自己手动加一个滚动条,然后通过监听scroll,算出应该显示到第几个,通过计算属性截取显示的数据,直接上代码

    <!-- 列表元素 使用相对定位 -->
    <div class="projectInfo" @scroll="scrollListener" ref="listWrap">

      <!-- 设置一个不可见元素撑起这个列表 让列表的滚动条出现 -->
      <div class="scroll-bar" ref="scrollBar"></div>
      <!-- 列表的可见元素 使用绝对定位,left、right、top设置为0 -->
      <div class="projectInfoBox" ref="list">
        <div class="productEach" @click="addShopping(item)" v-for="item in showList" :key="item.id">
          <div class="productImg">
            <img v-show="userInfo.userInfo.yw_type == 2" src="@/icon/catering.png" alt="" />
            <img v-show="userInfo.userInfo.yw_type == 1" src="@/icon/product.png" alt="" />
          </div>
          <!-- <div class="productText">{{ item.barcode }}</div> -->
          <div class="productText">
            <p>{{ item.name }}</p>
          </div>
          <div class="productDO">
            <p class="textMoney">¥{{ item.price }}</p>
          </div>
        </div>
      </div>
<script setup>
import {
  onMounted,
  ref,
  computed,
} from 'vue'
//首页的虚拟列表参数
let listWrap = ref(null)//列表元素
let itemHeight = ref(165) //每列元素的高度
let showNum = ref(30) //第一次显示多少元素
let scrollBar = ref(null) //虚拟滚动条
let list = ref(null) //超长显示的长度
let start = ref(0) //开始下标
let end = ref(24) //结束下标


onMounted(async () => {
//计算滚动容器高度
listWrap.value.height = itemHeight.value * showNum.value + 'px' //计算出
//计算总的数据需要的高度,构造滚动条
scrollBar.value.height =itemHeight.value * ProductList.ProductList.length + 'px'

})


//显示的商品
const showList = computed(() => {
    //ProductList 后端拿到的1万条数据  进行数据截取
  let arr = ProductList.slice(start.value, end.value)
  if (arr.length != 0) {
    //arr长度不等于0 就隐藏loading
    SettingStore.settingLoading(false)
  }
  return arr
})
//滚动事件
const scrollListener = () => {
  //获取滚动高度
  let scrollTop = listWrap.value.scrollTop
  //开始数据的索引
  start.value = Math.floor(scrollTop / itemHeight.value) * 6
  //结束索引
  end.value = start.value + showNum.value
  //绝对定位对相对定位的偏移量
  list.value.style.top = (start.value / 6) * itemHeight.value + 'px'
}

css就根据 你们的需求去操作吧。

 

Logo

前往低代码交流专区

更多推荐