货无忧
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

87 lines
2.5 KiB

<template>
<!-- @scrolltolower触底事件@scroll滚动事件 -->
<scroll-view scroll-y="true" :style="{height: containerHeight+'px'}" @scroll="scrollTop = $event.detail.scrollTop"
@scrolltolower="$emit('@scrolltolower')">
<!-- 监听滚动事件使用passive修饰符 -->
<view :style="paddingStyle">
<!-- key使用index可避免多次渲染该dom -->
<view id="box" v-for="(item, index) in showList" :key="index">
<!-- 使用作用域插槽将遍历后的数据item和index传递出去 -->
<slot :item="item" :$index="index"></slot>
</view>
</view>
</scroll-view>
</template>
<script>
export default {
name: "App",
props: {
// 所有数据
allList: {
type: Array,
default () {
return []
}
},
// 容器高度
containerHeight: {
type: Number,
default: 0
},
},
data() {
return {
oneHeight: 200, // 单个元素的高度,默认200.在mounted中会再次回去单个元素高度
scrollTop: 0 // 滚动距离
};
},
async mounted() {
// 计算单个元素的高度
await this.$nextTick(() => {
})
// uniapp中获取高度的兼容写法
const query = uni.createSelectorQuery();
console.log('query.select :>> ', query.select('#box').boundingClientRect);
query.select('#box').boundingClientRect(data => {
console.log('data :>> ', data);
this.oneHeight = data.height
}).exec();
},
computed: {
// 一屏多少条数据
showNum() {
return ~~(this.containerHeight / this.oneHeight) + 2;
},
// 开始索引
startIndex() {
// 可见区域,第一个元素的index
const curIndex = ~~(this.scrollTop / this.oneHeight)
// console.log(this.showNum, this.oneHeight)
// 渲染区域第一个元素的index,这里缓冲区域的列表条数使用的是this.showNum
return curIndex < this.showNum ? 0 : curIndex - this.showNum
},
// 渲染元素最后的index
endIndex() {
// 可见区域,第一个index
const curIndex = ~~(this.scrollTop / this.oneHeight)
let end = curIndex + this.showNum * 3; // 2倍是需要预留缓冲区域
let len = this.allList.length
return end >= len ? len : end; // 结束元素大于所有元素的长度时,就取元素长度
},
// 需要渲染的数据
showList() {
return this.allList.slice(this.startIndex, this.endIndex)
},
// 空白占位的高度
paddingStyle() {
return {
paddingTop: this.startIndex * this.oneHeight + 'px',
paddingBottom: (this.allList.length - this.endIndex) * this.oneHeight + 'px'
}
}
},
};
</script>