目录Vue虚拟化列表封装将下面代码复制一份到自己的项目中 vue虚拟列表-vue-virtual-scroll-list使用场景安装使用vue虚拟化列表封装 将下面代码复制
<template>
<div class="scrollParent" ref="scrollContent" @scroll="handleScroll">
<div :style="blankFillStyle">
<div v-for="item,index in showDataList" :key="index">
<slot :everyVirtual="item"></slot>
</div>
</div>
</div>
</template>
<script>
export default {
props:["oneHeight","virtualList"],
data () {
return {
contentSize:"", //可视区域可以展示多少条数据
startIndex:0, //记录当前滚动的第一个元素的索引
currentScroll:0, //记录当前滚动的距离
}
},
methods:{
// 获取可视区域可以展示多少条
getContentSize(){
// 两次取反可以获取到整数部分
this.contentSize = ~~(this.$refs.scrollContent.offsetHeight / this.oneHeight) + 2;
},
// 监听滚动条
handleScroll(){
// 持续滚动 减少变量重新赋值 优化处理 只有在到下一个元素节点的时候才会重新给this.statrIndex赋值 避免和this.startIndex相关联的数据再次计算
this.currentScroll = this.$refs.scrollContent.scrollTop;
let currentIndex = ~~(this.$refs.scrollContent.scrollTop/this.oneHeight);
if(this.startIndex == currentIndex){
return
}
this.startIndex = currentIndex;
if((this.startIndex + this.contentSize - 1)>this.virtualList.length-1){ //说明到达底部了
this.$emit("scrollEnd")
}
}
},
activated(){
this.$nextTick(()=>{
this.$refs.scrollContent.scrollTop = this.currentScroll;
})
},
computed:{
endIndex(){ //获取最后一个元素的索引
let endIndex = this.startIndex + this.contentSize*2;
if(endIndex>this.virtualList.length-1){
endIndex = this.virtualList.length-1
}
return endIndex;
},
showDataList(){
let startIndex = 0;
if(this.startIndex<=this.contentSize){
startIndex = 0;
}else{
startIndex = this.startIndex - this.contentSize;
}
return this.virtualList.slice(startIndex,this.endIndex);
},
blankFillStyle(){
let startIndex = 0;
if(this.startIndex<=this.contentSize){
startIndex = 0;
}else{
startIndex = this.startIndex - this.contentSize;
}
return{
paddingTop:startIndex * this.oneHeight + "px",
paddingBottom:(this.virtualList.length - this.endIndex) * this.oneHeight +"px"
}
}
},
mounted(){
window.onresize = this.getContentSize();
window.orientationchange = this.getContentSize();
}
}
</script>
<style scoped>
.scrollParent{
height: 100%;
width: 100%;
overflow-y: auto;
}
</style>
因为公司做了类似于百度网盘的竞品,所以用户如果上传了很多的文件,就会造成页面DOM元素的过多,然后因为需要操作DOM元素,所以页面会变得很卡。所以用虚拟列表来解决。
安装的话这个插件有2个版本的,一个是1版本,目前更新到2版本了,二版本功能更加的强大。这里使用了1版本,通俗易懂一点。
npm install --save vue-virtual-scroll-list@1.1.3
在单页面中导入
import VirtualList from "vue-virtual-scroll-list";
components: {
VirtualList,//注册组件
},
<div class="content-timeview_box">
<!-- size代表行高 remain代表一次渲染的数量 -->
<!-- 出现的问题:1.在时间视图时(文件夹视图只有一个VirtualList不受影响) 一个日期代表一个VirtualList 怎么解决高度问题? -->
<!-- 如果统一高度?一个日期中的文件数量少于高度 就会出现VirtualList之间的空白问题 -->
<!-- 应该根据日期下的文件数量来动态的绑定每一个VirtualList的高度 -->
<VirtualList
:size="40"
:remain="17"
:wclass="vuesrollboxviewClass"
:tobottom="toBottom"
style="padding: 0 32px 0 32px"
:style="{height:itembig.items.length>6?scrollbarheight:'200px'}"
>
toBottom
的方法,这个地方就很坑,因为我只能在1.1.3版本中触发这个方法,1版本的其他版本号我没有触发成功,应该还是高度的问题。toBottom
:滚动到底部时触发,请求下一组数据 //滚到底部时触发
//注:此方法在1.0高版本不兼容,只能在官方文档1.1.3版本中使用
//@1.1.3
toBottom() {
this.infiniteHandler();
},
:wclass=“vuesrollboxviewClass”
wclass是自定义的class,我这里的业务场景不是每行只有1个数据,从上而下排列下来,而是每行根据分辨率不同,展示5个或6个,所以得计算好一次渲染的个数,需要动态的绑定。
小结:还是需要更熟练的掌握原生js,虽然有各种各样的框架插件来解决问题,但是碰到业务场景更复杂的时候呢?所以还是要掌握原生JS,具备自己写轮子的能力才行。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
--结束END--
本文标题: vue虚拟化列表封装的实现
本文链接: https://lsjlt.com/news/150579.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0