From 549082443bb68223a6ca2b360003c4c665a2c060 Mon Sep 17 00:00:00 2001 From: Fedorov Vladimir Date: Tue, 14 Jul 2026 23:55:32 +0700 Subject: [PATCH] add use api --- src/composables/useApi.ts | 65 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/composables/useApi.ts diff --git a/src/composables/useApi.ts b/src/composables/useApi.ts new file mode 100644 index 0000000..7eafe49 --- /dev/null +++ b/src/composables/useApi.ts @@ -0,0 +1,65 @@ +import { ref, type Ref } from 'vue'; + +export type ApiMethod = (params: P) => Promise; + +interface UseApiOptions { + immediate?: boolean; + onSuccess?: (data: T) => void; + onError?: (error: Error) => void; +} + +export function useApi( + method: ApiMethod, + params?: P, + options: UseApiOptions = {} +) { + const data = ref(null) as Ref; + const loading = ref(false); + const error = ref(null); + + const execute = async (execParams?: P) => { + loading.value = true; + error.value = null; + + try { + const result = await method(execParams !== undefined ? execParams : (params as P)); + data.value = result; + options.onSuccess?.(result); + return result; + } catch (e) { + const err = e instanceof Error ? e : new Error('Unknown error'); + error.value = err; + options.onError?.(err); + throw err; + } finally { + loading.value = false; + } + }; + + const reset = () => { + data.value = null; + loading.value = false; + error.value = null; + }; + + // Автоматический запуск + if (options.immediate !== false) { + execute(); + } + + return { + data, + loading, + error, + execute, + reset, + }; +} + +// Упрощенная версия для GET-запросов +export function useApiData( + method: ApiMethod, + params?: P +) { + return useApi(method, params, { immediate: true }); +}