<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>