什么是长列表
前端业务会涉及到数据量很大的且无法用分页进行加载的列表,我们一般叫做长列表,
完整的渲染长列表基本上很难达到业务的上的要求,非完整渲染长列表一般分为两种:
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就根据 你们的需求去操作吧。