虚拟列表
- 实现思路
首先先创建一个div容器,给它添加样式代码,超出部分以滚动条形式出现。然后我们在这个div容器里面,创建两个同级的div,一个名为bar的div用来撑起来高度,因为我们后面要滚动盒子,高度必须撑开;另一个名为list,存放item项,这个list不需要设置高度,但要设置相对定位,因为这个主要思路就是靠bar把高度撑开,然后给list定位脱离文档流,直接定位在可视区域,每次滚动的时候就修改list的top值就可以实现效果。
这样可以使页面dom始终都保持在固定数量,可以大大提高页面性能,非常受欢迎。
- 实现代码
html代码
<template>
<!-- div容器 -->
<div
class="virtual"
@scroll="handleScroll"
:style="{ height: viewPort + 'px' }"
>
<!-- 滚动条 -->
<div class="bar" ref="bar"></div>
<!-- 列表区域 -->
<div class="virtual-list" ref="list">
<div class="virtual-list-item" v-for="item in virtualData" :key="item">
{{ item }}
</div>
</div>
</div>
</template>
//css样式代码
.virtual {
position: relative;
width: 400px;
margin-left: 50px;
border: 1px solid blue;
overflow-y: scroll;
}
.virtual::-webkit-scrollbar {
display: none;
}
.virtual-list {
position: absolute;
width: 100%;
}
.virtual-list-item {
width: 100%;
background: #efefef;
margin: 10px 0;
text-align: center;
line-height: 100px;
}
vue代码
> export default {
name: "VirtualList",
data() {
return {
data: [],
virtualData: [], //存放显示的数据
itemHeight: 100, //item项的高度
showNum: 6, //显示的数量
};
},
computed: {
//计算可视区域的高度
viewPort() {
return this.itemHeight * this.showNum;
},
},
mounted() {
//构造一个超长列表
for (let i = 0; i < 100; i++) {
this.data.push("列表" + i);
}
this.updateVirtual();
let temp = this.itemHeight * this.data.length;
this.$refs.bar.style.height = temp + "px";
},
methods: {
handleScroll(e) {
this.updateVirtual(e.target.scrollTop);
},
updateVirtual(top) {
const scrollTop = top || 0;
const start = Math.ceil(scrollTop / this.itemHeight);
const end = this.showNum + start;
this.virtualData = this.data.slice(start, end);
//绝对定位对相对定位的偏移量
this.$refs.list.style.top = start * this.itemHeight + "px";
},
},
};
</script>
- 实现效果
我们通过css样式代码,隐藏滚动条,效果更加不错