<template>
    <div
        ref="boxRef"
        class="box"
        v-loading="loading"
        @scroll.passive="handleScroll"
    >
        <div ref="contentRef">
            <h2
                v-for="(item, index) in list"
                :key="index"
            >
                {{ item }}
            </h2>
            <h1>请使用移动端调试模式打开</h1>
            <h2>这里是模拟数据1</h2>
            <h2>这里是模拟数据1</h2>
            <h2>这里是模拟数据1</h2>
            <h2>这里是模拟数据1</h2>
            <h2>这里是模拟数据1</h2>
            <h2>首屏数据到此</h2>
            <h2>模拟数据不够一页下拉加载</h2>
        </div>
    </div>
</template>

<script setup lang="jsx">
/**
 * 自动下拉加载数据注意事项
 * 1. 布局容器必须是一个外层box，并且设置高度，纵向允许滚动,否则监听滚动事件不生效 大约是 => 100vh => 667px这种(举例高度，设备不一样高度不一样)
 * 2. 内容容器content, 自动高度，由内容决定，滚动时其高度一定是超过容器高度的 如果有三页内容，高度为(667 * 3)px
 */
import { ref, onMounted, nextTick } from 'vue';
import { debounce } from '@pureadmin/utils';

const boxRef = ref(null);
const contentRef = ref(null);
const list = ref([]);
const loading = ref(false);
const beforeHeight = ref(null);

const getData = (isFirstLoadData = false) => {
    console.log(contentRef.value.clientHeight, '内部内容的整体高度');
    loading.value = true;
    console.log('加载数据');
    beforeHeight.value = contentRef.value.clientHeight;
    setTimeout(() => {
        loading.value = false;
        let tempList = [];
        let currentLength = list.value.length;
        for (let i = 20; i > 0; i--) {
            tempList.push(`模拟数据${i + currentLength}`);
        }
        list.value = tempList.concat(list.value);
        if (isFirstLoadData) {
            // 首次默认加载数据滚动到最后
            nextTick(() => contentRef.value.scrollIntoView(false));
        } else {
            // 下拉加载数据，滚动条滚动到加载数据前位置
            nextTick(() => (boxRef.value.scrollTop = contentRef.value.clientHeight - beforeHeight.value));
        }
    }, 2000);
};

const scrollLoadData = () => {
    console.log('监听滚动事件');
    const { scrollTop } = boxRef.value;
    console.log(scrollTop, '整个容器当前滚动条位置');
    console.log(contentRef.value.clientHeight, '内部内容的整体高度');
    if (scrollTop < 20) {
        getData(false);
    }
};

const handleScroll = debounce(scrollLoadData, 500);

onMounted(() => {
    getData(true);
});
</script>

<style lang="scss" scoped>
.box {
    display: flex;
    flex-direction: column;
    align-items: center;
    background: #fff;
    // 要监听滚动事件，必须设置高度，并且设置滚动为auto，否则监听事件不生效
    height: calc(100vh - 81px);
    overflow-y: auto;

    h2 {
        height: 150px;
    }
}
</style>
