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

121 lines
3.5 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div
ref="boxRef"
class="box"
v-loading="loading"
>
<div ref="contentRef">
<h3>———下拉加载更多数据———</h3>
<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">
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { debounce } from '@pureadmin/utils';
import { useBodyClass } from '@/hooks/useBodyClass';
useBodyClass('body-overflow-hidden');
const boxRef = ref(null);
const contentRef = ref(null);
const list = ref([]);
const loading = ref(false);
let startY = 0;
const beforeHeight = ref(null);
const getData = () => {
console.log(contentRef.value.clientHeight, '内部内容的整体高度');
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);
// 下拉加载数据,滚动条滚动到加载数据前位置
nextTick(() => (boxRef.value.scrollTop = contentRef.value.clientHeight - beforeHeight.value));
}, 2000);
};
const handleTouchstart = (e) => {
startY = e.touches[0].clientY;
};
const handleTouchmove = (e) => {
console.log('监听鼠标移动事件', e);
if (!shouldHandleTouch()) {
return;
}
const currentY = e.touches[0].clientY;
if (currentY - startY > 100) {
e.preventDefault && e.preventDefault();
loading.value = true;
// 这里调用是因为debounce的原因debounc会延迟导致touchend事件先执行所以这里需要手动触发一次
handleTouchend();
}
};
const debounceHandleTouchmove = debounce(handleTouchmove, 100);
const handleTouchend = () => {
if (loading.value) {
getData();
}
};
const shouldHandleTouch = () => {
console.log(boxRef.value.scrollTop, '整个容器当前滚动条位置');
if (boxRef.value.scrollTop > 0 || loading.value) {
return false;
}
return true;
};
const addTouchEventListeners = () => {
boxRef.value.addEventListener('touchstart', handleTouchstart);
boxRef.value.addEventListener('touchmove', debounceHandleTouchmove);
boxRef.value.addEventListener('touchend', handleTouchend);
};
const removeTouchEventListeners = () => {
boxRef.value.removeEventListener('touchstart', handleTouchstart);
boxRef.value.removeEventListener('touchmove', debounceHandleTouchmove);
boxRef.value.removeEventListener('touchend', handleTouchend);
};
onMounted(() => {
addTouchEventListeners();
});
onBeforeUnmount(() => {
removeTouchEventListeners();
});
</script>
<style lang="scss" scoped>
.box {
display: flex;
flex-direction: column;
align-items: center;
background: #fff;
height: calc(100vh - 81px);
overflow-x: hidden;
overflow-y: auto;
h2 {
padding: 10px 0;
}
}
</style>