虚拟滚动列表(固定高)

描述:滚动列表数据量庞大的时候(如一万条数据),会在页面创建一万个DOM元素,而页面的DOM太多会对页面的渲染造成很大的负担,出现页面卡顿等情况,严重的减少用户体验感,所以需要使用虚拟滚动列表,对长列表功能模块进行优化。
在这里插入图片描述

在head中导入vue

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

css

* {
  margin: 0;
  padding: 0;
}

.container {
  width: 280px;
  height: 500px;
  margin: 50px auto;
  border: 1px solid #ccc;
  overflow: auto;
}

.contentBox {
  position: relative;
}

.cell {
  position: absolute;
  left: 0;
  line-height: 25px;
}

html

<div id="app">
  <div class="container">
    <div class="contentBox">
      <p class="cell" v-for="(item, index) in showList" :key="index" :style="{top: item.top}">{{item.data}}</p>
    </div>
  </div>
</div>

js

window.onload = function () {
 var vue = new Vue({
   el: '#app',
   data: {
     // 全部数据量
     list: new Array(10000).fill(0).map((item, index) => ('内容' + (index + 1))),
     // 展示的数据
     showList: [
       { data: '暂无数据', top: 0 }
     ],
     // 每行高度
     cellHeight: 0,
     // 可视框显示的数据量
     showCount: 0
   },
   methods: {
     // 初始化基本参数
     initData() {
       let containerDom = document.querySelector('.container')
       let contentBoxDom = document.querySelector('.container .contentBox')
       let cell = document.querySelector('.cell')
       // 盒子高度
       let containerDomHeight = containerDom.clientHeight
       // 每行高度
       this.cellHeight = cell.clientHeight
       // 可视框需要显示的数据量
       this.showCount = Math.ceil(containerDomHeight / this.cellHeight)
       // 滚动盒子的高度
       contentBoxDom.style.height = this.cellHeight * this.list.length + 'px'

       // 实现虚拟滚动
       this.initScrolLoad(containerDom)
       containerDom.onscroll = () => {
         this.initScrolLoad(containerDom)
       }
     },
     // 实现虚拟滚动
     initScrolLoad(containerDom) {
       // 滚动出去的距离
       let scrollTop = containerDom.scrollTop
       // 可视区域第一行索引(-2: 往上多渲染两条数据)
       let startIndex = Math.floor(scrollTop / this.cellHeight) - 2
       // 可视区域最后一行索引(+4: 往下多渲染两条数据(要算上上面的-2))
       let endIndex = startIndex + this.showCount + 4
       
       // 获取需要渲染的数据
       this.showList = []
       for (let i = startIndex; i < endIndex; i++) {
         this.showList.push({
           data: this.list[i],
           // 算好每个元素需要的top值
           top: i * this.cellHeight + 'px'
         })
       }
       // console.log(startIndex, endIndex)
     },
   },
   mounted() {
     this.initData()
   }
 })
}

如列表项高度不固定,可使用虚拟滚动列表(动态高)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值