Files
Friendship-and-chat-uniapp/sheep/hooks/use-scroll.ts
T
2025-11-11 21:58:44 +08:00

97 lines
2.4 KiB
TypeScript

import { onMounted, reactive, ref } from "vue";
export default function useScroll(fetchList: (...arg: any) => Promise<any>) {
const refresherTriggered = ref(false);
const loadMoreContent = reactive({
contentdown: " ",
contentrefresh: "正在加载...",
contentnomore: "没有更多数据了",
});
const loadMoreStatus = ref<"more" | "loading" | "noMore">("more");
const listData = ref<any[]>([]);
const pageInfo = reactive({
current: 1,
total: 0,
hasMore: true,
});
onMounted(() => {
loadData(false);
});
const loadData = async (isRefresh: boolean = false) => {
try {
if (pageInfo.current === 1) {
uni.showLoading({ title: "加载中..." });
}
if (isRefresh) {
pageInfo.current = 1;
const { total, data } = await fetchList(pageInfo.current);
listData.value = data;
pageInfo.total = total;
} else {
const { total, data } = await fetchList(pageInfo.current);
listData.value.push(...data);
pageInfo.total = total;
}
pageInfo.current = pageInfo.current + 1;
if (listData.value.length >= pageInfo.total) {
loadMoreStatus.value = "noMore";
} else {
loadMoreStatus.value = "more";
}
return true;
} catch (error) {
console.error("加载数据失败:", error);
return false;
} finally {
uni.hideLoading();
}
};
// 触发下拉刷新
const onRefresherRefresh = async () => {
refresherTriggered.value = true;
const success = await loadData(true);
refresherTriggered.value = false;
if (success) {
uni.showToast({ title: "刷新成功", icon: "success" });
}
};
// 下拉刷新中止
const onRefresherAbort = () => {
console.log("下拉刷新中止");
refresherTriggered.value = false;
};
// 触发上拉加载
const onScrollToLower = async () => {
if (loadMoreStatus.value === "loading" || loadMoreStatus.value === "noMore") {
return;
}
loadMoreStatus.value = "loading";
await loadData(false);
};
// 点击加载更多
const onClickLoadMore = () => {
if (loadMoreStatus.value === "more") {
onScrollToLower();
}
};
return {
listData,
refresherTriggered,
loadMoreContent,
loadMoreStatus,
onRefresherRefresh,
onRefresherAbort,
onScrollToLower,
onClickLoadMore,
};
}