98 lines
2.0 KiB
Vue
98 lines
2.0 KiB
Vue
<script setup>
|
|
import { ref } from "vue";
|
|
import { onShow } from "@dcloudio/uni-app";
|
|
const props = defineProps({
|
|
show: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
onLoading: {
|
|
type: Function,
|
|
default: async (page) => [],
|
|
},
|
|
pageSize: {
|
|
type: Number,
|
|
default: 10,
|
|
},
|
|
});
|
|
const refreshing = ref(true);
|
|
const loading = ref(false);
|
|
const noMore = ref(false);
|
|
const count = ref(0);
|
|
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);
|
|
count.value = length;
|
|
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);
|
|
count.value += length;
|
|
if (length < props.pageSize) noMore.value = true;
|
|
} finally {
|
|
loading.value = false;
|
|
}
|
|
};
|
|
onShow(async () => {
|
|
try {
|
|
const length = await props.onLoading(page.value);
|
|
count.value = length;
|
|
if (length < props.pageSize) noMore.value = true;
|
|
} finally {
|
|
refreshing.value = false;
|
|
}
|
|
});
|
|
</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>
|
|
<view class="tips">
|
|
<text v-if="loading">加载中...</text>
|
|
<text v-if="noMore">{{ count === 0 ? "暂无数据" : "没有更多了" }}</text>
|
|
</view>
|
|
</scroll-view>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.scroll-list {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
.tips {
|
|
height: 50rpx;
|
|
}
|
|
.tips > text {
|
|
color: #d0d0d0;
|
|
display: block;
|
|
text-align: center;
|
|
font-size: 12px;
|
|
margin: 10px;
|
|
}
|
|
</style>
|