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