uniapp封装虚拟列表滚动组件
这里用到一个列表,然后数据可能有很多很多…,一次性全部渲染到dom上会卡顿,很废性能,于是用了这个虚拟列表就变丝滑很多很多。
组件mosoweInventedList 代码:
<!-- 虚拟滚动列表组件:mosoweInventedList -->
<template><view class="mosowe-invented-list"><scroll-view class="container" scroll-y :style="{ height: boxHeight + 'px' }" @scroll="handleScroll"><div class="mosowe-invented-wrap" :style="{ height: itemHeight * list.length + 'px' }"><div class="mosowe-invented-content" :style="{ transform: 'translateY(' + offsetY + 'px)' }"><view class="mosowe-invented-item" v-for="(item, index) in showList" :key="index"><slot :item="item"></slot></view></div></div></scroll-view></view>
</template><script>export default {props: {list: {type: Array,default: () => []},cacheNum: {// 前后缓存数目type: Number,default: 10}},data() {return {showList: [], // 展示的数据列表boxHeight: 0, // 组件可视区高度itemHeight: 0, // 每条数据高度,计算第一条数据的高度,以第一条数据高度为主offsetY: 0};},computed: {pageNum() {if (this.boxHeight && this.itemHeight) {return Math.ceil(this.boxHeight / this.itemHeight) + this.cacheNum;} else {return this.cacheNum;}}},watch: {pageNum() {this.setShowList(0);},list: {handler() {this.init();},deep: true,immediate: true}},mounted() {this.init();},methods: {init() {this.$nextTick(() => {this.setShowList(0);let t = setTimeout(() => {clearTimeout(t);t = null;const query = uni.createSelectorQuery().in(this);query.select('.mosowe-invented-list').boundingClientRect((res) => {this.boxHeight = Math.floor(res?.height) || 0;}).select('.mosowe-invented-item').boundingClientRect((res) => {this.itemHeight = Math.floor(res?.height) || 0;}).exec();}, 100);});},handleScroll(e) {const scrollTop = Math.floor(e.detail.scrollTop);this.offsetY = scrollTop - (scrollTop % this.itemHeight);let startIndex = Math.floor(scrollTop / this.itemHeight);if (startIndex > this.cacheNum) {this.offsetY -= this.cacheNum * this.itemHeight;startIndex = startIndex - this.cacheNum;}this.setShowList(startIndex);this.$emit('scroll', scrollTop);},setShowList(startIndex) {this.showList = this.list.slice(startIndex, startIndex + this.pageNum);}}};
</script><style lang="scss" scoped>.mosowe-invented-list {overflow: hidden;height: 100%;width: 100%;.container {width: 100%;height: 100%;}}
</style>
使用:
<template><view class="centent"><mosoweInventedList :list="listData" :cacheNum="20"><template #default="{ item }"><view class="item"><view class="list"><view class="col title"><image class="mark" src="@/static/images/layout/rectangle_9.png" mode=""></image>{{ item.yhmc }}</view><view class="col area"><u-count-to fontSize="9rpx" style="color: #2EC38E;" class="unm" :endVal="item.mj"separator=","></u-count-to><text class="unit">k㎡</text></view><view class="col time">{{ item.jmrq }}</view></view><u-divider text=""></u-divider></view></template></mosoweInventedList></view>
</template>