use-request.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. import { ref } from 'vue';
  2. import type { Ref } from 'vue';
  3. import { createFlatRequest } from '@sa/axios';
  4. import type {
  5. AxiosError,
  6. CreateAxiosDefaults,
  7. CustomAxiosRequestConfig,
  8. MappedType,
  9. RequestInstanceCommon,
  10. RequestOption,
  11. ResponseType
  12. } from '@sa/axios';
  13. import useLoading from './use-loading';
  14. export type HookRequestInstanceResponseSuccessData<ApiData> = {
  15. data: Ref<ApiData>;
  16. error: Ref<null>;
  17. };
  18. export type HookRequestInstanceResponseFailData<ResponseData> = {
  19. data: Ref<null>;
  20. error: Ref<AxiosError<ResponseData>>;
  21. };
  22. export type HookRequestInstanceResponseData<ResponseData, ApiData> = {
  23. loading: Ref<boolean>;
  24. } & (HookRequestInstanceResponseSuccessData<ApiData> | HookRequestInstanceResponseFailData<ResponseData>);
  25. export interface HookRequestInstance<ResponseData, ApiData, State extends Record<string, unknown>>
  26. extends RequestInstanceCommon<State> {
  27. <T extends ApiData = ApiData, R extends ResponseType = 'json'>(
  28. config: CustomAxiosRequestConfig
  29. ): HookRequestInstanceResponseData<ResponseData, MappedType<R, T>>;
  30. }
  31. /**
  32. * create a hook request instance
  33. *
  34. * @param axiosConfig
  35. * @param options
  36. */
  37. export default function createHookRequest<ResponseData, ApiData, State extends Record<string, unknown>>(
  38. axiosConfig?: CreateAxiosDefaults,
  39. options?: Partial<RequestOption<ResponseData, ApiData, State>>
  40. ) {
  41. const request = createFlatRequest<ResponseData, ApiData, State>(axiosConfig, options);
  42. const hookRequest: HookRequestInstance<ResponseData, ApiData, State> = function hookRequest<
  43. T extends ApiData = ApiData,
  44. R extends ResponseType = 'json'
  45. >(config: CustomAxiosRequestConfig) {
  46. const { loading, startLoading, endLoading } = useLoading();
  47. const data = ref(null) as Ref<MappedType<R, T>>;
  48. const error = ref(null) as Ref<AxiosError<ResponseData> | null>;
  49. startLoading();
  50. request(config).then(res => {
  51. if (res.data) {
  52. data.value = res.data as MappedType<R, T>;
  53. } else {
  54. error.value = res.error;
  55. }
  56. endLoading();
  57. });
  58. return {
  59. loading,
  60. data,
  61. error
  62. };
  63. } as HookRequestInstance<ResponseData, ApiData, State>;
  64. hookRequest.cancelAllRequest = request.cancelAllRequest;
  65. return hookRequest;
  66. }