专业 网站设计,拼多多开网店无货源怎么上货,鄂州网吧什么时候恢复营业,dnf网站上怎么做商人作用#xff1a;
虚拟列表是优化长列表的一种手段#xff0c;防止列表存在过多的dom元素导致页面卡顿#xff08;包扣移动端下拉到底加载下一页这种列表加载的dom元素多了一样会卡#xff09;。 原理#xff1a; 如上图简单地说就是以 div classlist-view作…作用
虚拟列表是优化长列表的一种手段防止列表存在过多的dom元素导致页面卡顿包扣移动端下拉到底加载下一页这种列表加载的dom元素多了一样会卡。 原理 如上图简单地说就是以 div classlist-view作为固定窗口用来展示看到的数据。
用div classlist-view-phantom来撑起固定窗口的高度来出现滚动条。
用ul classlist-view-content来存放数据并且让他随着滚动条一起动达到视觉上的列表滚动。 优化的问题
在基础虚拟列表的基础上优化了如下几点
1.根据rem动态计算每一条数据在页面中对应的height和margin。
2.当窗口的resize事件触发一切数值都重新计算让列表底部样式不出错和滚动到底部不抖动。
3.向下滚动加载下一条数据时候卡在计算阈值内导致底部留白太大通过至多加载固定窗口对应展示数据的数量给追加到原本的结尾索引达到多渲染一屏窗口的数据。
4.加载数据到最后显示暂无更多数据文案。
5.自动滚动到指定数据项的位置。
6.页面不停快速刷新导致获取不到固定窗口高度和滚动到指定位置不起作用。 实现如下
templatediv reflistView classlist-view scrollhandleScrolldiv classlist-view-phantom :style{height: ${contentHeight}px}/divul classlist-view-content refcontent li classlist-view-item v-for(item, index) in visibleData :keyindex{{ item }}/lidiv v-iflastFlag styleheight:100px;line-height:50px;font-size:30px;color:black;暂无更多数据/div/ul/div
/template
script
export default {name: ListView,props: {data: {type: Array,default: function() {const list []for (let i 0; i 150; i) {list.push(列表 i)}return list}},itemHeight: {type: Number,default: 365},itemMargin: {type: Number,default: 80},},computed: {contentHeight() {return this.data.length * this.itemHeightRem this.data.length * this.itemMarginRem;},},watch:{data:{handler(){this.$nextTick((){this.init();})},deep:true},},mounted() {let that this;this.init();window.onresize function(){//加防抖if(that.timer){clearTimeout(that.timer);that.timernull;}that.timer setTimeout(() {that.init();}, 500);}},data() {return {//列表底部增加展示数据比例bufferScale:1,timer:null,itemHeightRem:,itemMarginRem:,listView:null,contentView:null,visibleData: [],//滚动到指定数据项docStatusIndex:0,lastFlag:false,};},methods: {init(){this.$nextTick((){let htmlFontSize document.documentElement.style.fontSize;//使用rem的项目中根据html的fontSize自动计算列表每一项的height和marginthis.itemHeightRem Number((this.itemHeight/(192/parseFloat(htmlFontSize)).toFixed(2)));this.itemMarginRem Number((this.itemMargin/(192/parseFloat(htmlFontSize)).toFixed(2)));this.listView this.$refs.listView;this.contentView this.$refs.content//自动滚动到指定数据索引位置this.listView.scrollTop this.docStatusIndex * (this.itemHeightRem this.itemMarginRem);//拦截刷新错误计算scrollTop计算为0 或者 获取不到$refs.listView和clientHeightif(!this.listView || this.listView.clientHeight 0 || (this.docStatusIndex 0 this.listView.scrollTop 0)){setTimeout(() {this.init();}, 300);return;}this.updateVisibleData(this.listView.scrollTop);})},updateVisibleData(scrollTop) {scrollTop scrollTop || 0;// 取得可见区域的可见列表项数量const visibleCount Math.ceil(this.listView.clientHeight / (this.itemHeightRem this.itemMarginRem)); // 取得可见区域的起始数据索引let start Math.floor(scrollTop / (this.itemHeightRem this.itemMarginRem)); // 取得可见区域的结束数据索引let end start visibleCount; //防止可见区域的数据展示超出data最大范围if(endthis.data.length start0){return;}//显示暂无更多文案if(end this.data.length){this.lastFlag true;}//end之后增加至多visibleCount条数据防止底部空白过大const belowCount Math.min(this.data.length - end,this.bufferScale * visibleCount);end end belowCount;//可见区域展示的数据this.visibleData this.data.slice(start, end); // 展示列表进行偏移this.contentView.style.webkitTransform translate3d(0,${scrollTop - (scrollTop % (this.itemHeightRem this.itemMarginRem))}px,0); },//要加节流handleScroll() {const scrollTop this.listView.scrollTop ;this.updateVisibleData(scrollTop);}}
}
/script
style scoped
.list-view {overflow: auto;position: relative;width: 100%;height:100%;box-sizing: border-box;
}.list-view-phantom {position: absolute;left: 0;top: 0;right: 0;z-index: -1;
}.list-view-content {top:0;left:0;right:0;position: absolute;
}.list-view-item {margin-bottom: 80px;;background-color: aqua;color: red;height:365px;line-height: 130px;width:100%;display: block;font-size: 140px;box-sizing: border-box;overflow: hidden;
}
/style