infinite-scroll.ts 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import { reactive, ref } from "vue";
  2. export function useInfiniteScroll<T = any>(
  3. pageSize: number,
  4. loadData: (page: number) => Promise<T[]>
  5. ) {
  6. const loading = ref(false);
  7. const page = ref(1);
  8. const hasNext = ref(false);
  9. const list = ref();
  10. const refresh = () => {
  11. if (loading.value) {
  12. return;
  13. }
  14. uni.showLoading({
  15. title: "加载中",
  16. });
  17. loading.value = true;
  18. return loadData(1)
  19. .then((res) => {
  20. uni.hideLoading();
  21. loading.value = false;
  22. page.value = 1;
  23. hasNext.value = res.length >= pageSize;
  24. list.value = res;
  25. uni.stopPullDownRefresh();
  26. })
  27. .catch(() => {
  28. uni.hideLoading();
  29. uni.stopPullDownRefresh();
  30. loading.value = false;
  31. });
  32. };
  33. const next = () => {
  34. if (hasNext.value) {
  35. if (loading.value) {
  36. return;
  37. }
  38. uni.showLoading({
  39. title: "加载中",
  40. });
  41. loading.value = true;
  42. return loadData(page.value + 1)
  43. .then((res) => {
  44. uni.hideLoading();
  45. loading.value = false;
  46. hasNext.value = res.length >= pageSize;
  47. if (!res || res.length <= 0) {
  48. return;
  49. }
  50. page.value = page.value + 1;
  51. res.forEach((item) => {
  52. list.value.push(item);
  53. });
  54. })
  55. .catch(() => {
  56. uni.hideLoading();
  57. hasNext.value = false;
  58. loading.value = false;
  59. });
  60. }
  61. };
  62. return reactive({
  63. page,
  64. loading,
  65. hasNext,
  66. list,
  67. refresh,
  68. next,
  69. });
  70. }