89 lines
1.8 KiB
Vue
89 lines
1.8 KiB
Vue
<script setup>
|
|
import { ref, watch } from "vue";
|
|
const props = defineProps({
|
|
show: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
onLoading: {
|
|
type: Function,
|
|
default: async (page) => [],
|
|
},
|
|
pageSize: {
|
|
type: Number,
|
|
default: 10,
|
|
},
|
|
});
|
|
const refreshing = ref(false);
|
|
const loading = ref(false);
|
|
const noMore = ref(false);
|
|
const page = ref(1);
|
|
const refresherrefresh = async () => {
|
|
if (refreshing.value) return;
|
|
try {
|
|
refreshing.value = true;
|
|
page.value = 1;
|
|
const length = await props.onLoading(page.value);
|
|
if (length < props.pageSize) noMore.value = true;
|
|
} finally {
|
|
refreshing.value = false;
|
|
}
|
|
};
|
|
const scrolltolower = async () => {
|
|
if (loading.value || noMore.value) return;
|
|
try {
|
|
loading.value = true;
|
|
page.value += 1;
|
|
const length = await props.onLoading(page.value);
|
|
if (length < props.pageSize) noMore.value = true;
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
watch(
|
|
() => props.show,
|
|
async (newVal) => {
|
|
if (newVal) await props.onLoading(1);
|
|
},
|
|
{
|
|
immediate: true,
|
|
}
|
|
);
|
|
</script>
|
|
|
|
<template>
|
|
<scroll-view
|
|
class="scroll-list"
|
|
scroll-y
|
|
:show-scrollbar="false"
|
|
enhanced="true"
|
|
:bounces="false"
|
|
refresher-default-style="white"
|
|
:refresher-enabled="true"
|
|
:refresher-triggered="refreshing"
|
|
@refresherrefresh="refresherrefresh"
|
|
@scrolltolower="scrolltolower"
|
|
:style="{
|
|
display: show ? 'flex' : 'none',
|
|
}"
|
|
>
|
|
<slot></slot>
|
|
<text class="tips" v-if="loading">加载中...</text>
|
|
<text class="tips" v-if="noMore">我是有底线的</text>
|
|
</scroll-view>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.scroll-list {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
.tips {
|
|
color: #fff9;
|
|
display: block;
|
|
text-align: center;
|
|
font-size: 12px;
|
|
margin: 10px;
|
|
}
|
|
</style>
|