vue自定义实现虚拟化列表
作者:互联网
1使用
<ViualList :size="40" :remain="8" :dataList="dataList"> </ViualList>
size:每个列表的高度Height
remain:当前屏幕展示数据个数
dataList:当前数据
2自定义组件ViualList
根据size和remain确定内容区域height
根据size和dataList长度确定滚动条height
<!-- 主高度 --> <div class="vitual-con" ref="vitualConRef" @scroll="handleScroll"> <!-- 滚动条 --> <div class="scroll-bar" ref="scrollBarRef"></div> <div class="scroll-list" ref="scrollListRef" :style="{ 'padding-top': `${this.scrollTop}px` }" > <div class="listItem" v-for="item in visibleData" :key="item.id" :style="{ height: `${size}px` }" > {{ item.id + "." + item.value }} </div> </div> </div>...... mounted() { //定义主屏幕高度 this.$refs.vitualConRef.style.height = this.size * this.remain + "px"; //定义滚动条高度 this.$refs.scrollBarRef.style.height = this.size * this.dataList.length + "px"; },.vitual-con { overflow-y: scroll; position: relative; } .scroll-list { position: absolute; top: 0; left: 0; }
控制当前页面只显示remain个数的数据可以根据滚动条来获取当前位置和数据
handleScroll() { this.start = Math.floor(this.$refs.vitualConRef.scrollTop / this.size); this.end = this.start + this.remain; },
在字符串中截取start到end数据,优化效果则设置预留数据
computed: { visibleData() { let start = this.start - this.preveCount; let end = this.end + this.nextCount; return this.dataList.slice(start, end); }, // 计算内容区域 当前距离顶部的距离----优化 scrollTop() { return this.start * this.size - this.size * this.preveCount; }, // 优化-----避免下方出现的空白和当用户快速滚动时,出现空白屏----解决:预留加载 preveCount() { // 前面预留的个数---- 当前面的个数小于 8 个时,有几个就预留几个 return Math.min(this.start, this.remain); }, nextCount() { // 后面预先加载的个数 return Math.min(this.end, this.dataList.length - this.end); }, },
以下是完整代码
<template> <!-- 主高度 --> <div class="vitual-con" ref="vitualConRef" @scroll="handleScroll"> <!-- 滚动条 --> <div class="scroll-bar" ref="scrollBarRef"></div> <div class="scroll-list" ref="scrollListRef" :style="{ 'padding-top': `${this.scrollTop}px` }" > <div class="listItem" v-for="item in visibleData" :key="item.id" :style="{ height: `${size}px` }" > {{ item.id + "." + item.value }} </div> </div> </div> </template> <script> export default { name: "ViualList", props: { size: { type: Number, default: 40, }, remain: { type: Number, default: 8, }, dataList: { type: Array, default: () => [], }, }, data() { return { start: 0, end: this.remain, }; }, computed: { visibleData() { let start = this.start - this.preveCount; let end = this.end + this.nextCount; return this.dataList.slice(start, end); }, // 计算内容区域 当前距离顶部的距离----优化 scrollTop() { return this.start * this.size - this.size * this.preveCount; }, // 优化-----避免下方出现的空白和当用户快速滚动时,出现空白屏----解决:预留加载 preveCount() { // 前面预留的个数---- 当前面的个数小于 8 个时,有几个就预留几个 return Math.min(this.start, this.remain); }, nextCount() { // 后面预先加载的个数 return Math.min(this.end, this.dataList.length - this.end); }, }, mounted() { //定义主屏幕高度 this.$refs.vitualConRef.style.height = this.size * this.remain + "px"; //定义滚动条高度 this.$refs.scrollBarRef.style.height = this.size * this.dataList.length + "px"; }, methods: { handleScroll() { // console.log(this.$refs.vitualConRef.scrollTop); this.start = Math.floor(this.$refs.vitualConRef.scrollTop / this.size); this.end = this.start + this.remain; }, }, }; </script> <style> .vitual-con { overflow-y: scroll; position: relative; } .scroll-list { position: absolute; top: 0; left: 0; } </style>
标签:vue,end,自定义,虚拟化,dataList,start,remain,return,size 来源: https://www.cnblogs.com/lijun12138/p/16631889.html