SimpleDataLoader.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { onMounted, ref, type Ref } from "vue";
  2. import type { ILoaderCommon, LoaderLoadType } from "./LoaderCommon";
  3. export interface ISimpleDataLoader<T, P> extends ILoaderCommon<P> {
  4. content: Ref<T|null>;
  5. getLastParams: () => P | undefined;
  6. }
  7. export function useSimpleDataLoader<T, P = any>(
  8. loader: (params?: P) => Promise<T>,
  9. loadWhenMounted = true,
  10. emptyIfArrayEmpty = true,
  11. ) : ISimpleDataLoader<T, P>
  12. {
  13. const content = ref<T|null>(null) as Ref<T|null>;
  14. const loadStatus = ref<LoaderLoadType>('loading');
  15. const loadError = ref('');
  16. let lastParams: P | undefined;
  17. async function loadData(params?: P) {
  18. if (params)
  19. lastParams = params;
  20. loadStatus.value = 'loading';
  21. try {
  22. const res = (await loader(params ?? lastParams)) as T;
  23. content.value = res;
  24. if (Array.isArray(res) && emptyIfArrayEmpty && (res as any[]).length === 0)
  25. loadStatus.value = 'nomore';
  26. else
  27. loadStatus.value = 'finished';
  28. loadError.value = '';
  29. } catch(e) {
  30. loadError.value = '' + e;
  31. loadStatus.value = 'error';
  32. console.log(e);
  33. }
  34. }
  35. onMounted(() => {
  36. if (loadWhenMounted) {
  37. setTimeout(() => {
  38. loadData();
  39. }, (0.5 + Math.random()) * 500);
  40. }
  41. })
  42. return {
  43. content,
  44. loadStatus,
  45. loadError,
  46. loadData,
  47. getLastParams: () => lastParams,
  48. }
  49. }
  50. export async function useSSrSimpleDataLoader<T, P = any>(
  51. name: string,
  52. loader: (params?: P) => Promise<T>,
  53. params : P|undefined = undefined,
  54. emptyIfArrayEmpty = true,
  55. ) : Promise<ISimpleDataLoader<T, P>>
  56. {
  57. const route = useRoute();
  58. let lastParams: P | undefined = params;
  59. const loadStatus = ref<LoaderLoadType>('finished');
  60. const loadError = ref('');
  61. const { data: content, error } = (await useAsyncData(route.fullPath + '/' + name, () => loader(lastParams)))
  62. async function loadData(params?: P, refresh: boolean = false) {
  63. if (!import.meta.client)
  64. return;
  65. if (params)
  66. lastParams = params;
  67. loadStatus.value = 'loading';
  68. try {
  69. const res = await loader(params ?? lastParams) as T;
  70. content.value = res as any;
  71. if (Array.isArray(res) && emptyIfArrayEmpty && (res as any[]).length === 0)
  72. loadStatus.value = 'nomore';
  73. else
  74. loadStatus.value = 'finished';
  75. loadError.value = '';
  76. } catch(e) {
  77. loadError.value = '' + e;
  78. loadStatus.value = 'error';
  79. console.log(e);
  80. }
  81. }
  82. watch(error, (e) => {
  83. if (e) {
  84. loadError.value = '' + e;
  85. loadStatus.value = 'error';
  86. }
  87. }, { immediate: true });
  88. return {
  89. content: content as Ref<T|null>,
  90. loadStatus,
  91. loadError,
  92. loadData,
  93. getLastParams: () => lastParams,
  94. }
  95. }