购物车页面,通过计算当前可视区域的商品和高度,用虚拟列表的方式只渲染可视区域内的数据
一个商品选项的高度
可视区域高度
展示商品的数量等于可视区域高度/一个商品选项的高度
滑动条距离顶部的距离
this.$el.clienHeight 水平滚动条的高度 (如果存在) ,不然就是屏幕高度
讲一讲实现实现过程
首先通过给元素添加ref,.clientHeight获得可视区域高度,再设置列表每项高度,获得当前页面可展示多少项
监听onScroll事件触发时,通过ref获取滚动离顶部的距离scrolltop,
改变开始项和结束项从全部列表取数据到页面上进行渲染
监听虚拟列表滚动更换可视区内容
<template><div id="app"><!-- 包裹可视区域的可滚动的虚拟列表 --><div class="fictitious" @scroll="onScroll($event)" ref="ftwh" ><!-- 占位元素,高度为总列表高度,提供滚动条,通过绝对定位脱离普通文档流不占父元素高度 --><div :style="{height: phantomHeight+'px'}" class="seize"></div><!-- 可视区域 --><div class="LookCant" :style="{transform: getTransform}"><p v-for="item of lookArr" :key="item" :style="{height: rowHeight +'px'}" class="pp">{{item}}</p></div></div></div></template><script>export default {data(){return {//总列表数据arr:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99],//可视高度height: 0,//列表元素高度rowHeight: 100,//开始索引starItem:0,//结束索引endItem:0,//滑动条离顶部距离startOffset:0}},methods: {onScroll(){if((this.$refs.ftwh.scrollTop/this.rowHeight+this.limit)>this.total){this.endItem = this.totalreturn false}this.startOffset = this.$refs.ftwh.scrollTopthis.starItem = Math.floor(this.startOffset/this.rowHeight);this.endItem = this.starItem+this.limit;console.log(this.lookArr);console.log(this.startOffset);}},computed:{// 总条数total(){return this.arr.length;},//列表总高度phantomHeight(){return this.arr.length*this.rowHeight;},//可视范围内可展示元素数量limit(){return Math.ceil(this.height/this.rowHeight)},//真实显示的列表数据lookArr(){return this.arr.slice(this.starItem,Math.min(this.arr.length,this.endItem));},getTransform(){return `translate(0,${this.startOffset}px)`;}},mounted() {this.height = this.$el.clientHeight;this.starItem = 0;this.endItem = this.starItem+this.limit;},}</script><style>html{height: 100%;}body{margin: 0;padding: 0;height: 100%;}#app{height: 100%;}.fictitious{height: 100%;position: relative;overflow-y:auto;}.pp{box-sizing: border-box;padding: 10px 0;text-align: center;background-color: #999;margin: 0;border-bottom: 1px solid #fff;line-height: 100px;}.seize{z-index: -1;position: absolute;top: 0;left: 0;right: 0;}</style>
