SimplePageListLoader.ts 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { onPullDownRefresh, onReachBottom } from "@dcloudio/uni-app";
  2. import { computed, onMounted, ref, type Ref } from "vue";
  3. import type { ILoaderCommon, LoaderLoadType } from "./LoaderCommon";
  4. export interface ISimplePageListLoader<T, P> extends ILoaderCommon<P> {
  5. list: Ref<T[]>;
  6. page: Ref<number>;
  7. total: Ref<number>;
  8. }
  9. /**
  10. * 说明:
  11. * * 简单页面分页列表加载器组合式代码。
  12. * @param pageSize 每页数量
  13. * @param loader 数据加载函数
  14. * @param showGlobalLoading 是否显示全局加载提示
  15. */
  16. export function useSimplePageListLoader<T, P = any>(
  17. pageSize: number,
  18. loader: (page: number, pageSize: number, params?: P) => Promise<{ list: T[], total: number }>,
  19. loadWhenMounted = true,
  20. showGlobalLoading = false,
  21. ) : ISimplePageListLoader<T, P>
  22. {
  23. const status = ref<LoaderLoadType>('loading');
  24. const error = ref('');
  25. const page = ref(0);
  26. const total = ref(0);
  27. const list = ref<T[]>([]) as Ref<T[]>;
  28. let lastParams: P | undefined;
  29. let loading = false;
  30. async function load(refresh: boolean = false, params?: P) {
  31. if (loading)
  32. return;
  33. if (params)
  34. lastParams = params;
  35. if (refresh) {
  36. page.value = 0;
  37. list.value = [];
  38. }
  39. page.value++;
  40. status.value = 'loading';
  41. loading = true;
  42. if (showGlobalLoading)
  43. uni.showLoading({ title: '加载中...' });
  44. try {
  45. const res = (await loader(page.value, pageSize, lastParams));
  46. list.value = list.value.concat(res.list as T[]);
  47. total.value = res.total;
  48. status.value = res.list.length > 0 ? 'finished' : (list.value.length > 0 ? 'nomore' : 'empty');
  49. error.value = '';
  50. loading = false;
  51. } catch(e) {
  52. console.error(e);
  53. error.value = '' + e;
  54. status.value = 'error';
  55. loading = false;
  56. } finally {
  57. if (showGlobalLoading)
  58. uni.hideLoading();
  59. }
  60. }
  61. onPullDownRefresh(() => {
  62. load(true, lastParams).then(() => {
  63. uni.stopPullDownRefresh();
  64. }).catch(() => {
  65. uni.stopPullDownRefresh();
  66. });
  67. });
  68. onReachBottom(() => {
  69. if (status.value == 'nomore')
  70. return;
  71. load(false, lastParams);
  72. });
  73. onMounted(() => {
  74. if (loadWhenMounted)
  75. load(false, lastParams);
  76. })
  77. const isLoaded = computed(() => {
  78. return status.value === 'finished' || status.value === 'nomore';
  79. });
  80. return {
  81. list,
  82. total,
  83. page,
  84. status,
  85. error,
  86. load,
  87. reload: () => load(true),
  88. isLoaded,
  89. }
  90. }