Back
Syntax
Study
Editor
Mode:
HTML
CSS
JavaScript
PHP
Reset
Run »
HTML / CSS / JS
// src/composables/useFetch.ts import { ref, watchEffect, toValue, type MaybeRefOrGetter } from 'vue'; export function useFetch<T>(url: MaybeRefOrGetter<string>) { const data = ref<T | null>(null); const error = ref<Error | null>(null); const isLoading = ref(false); watchEffect(async (onCleanup) => { const controller = new AbortController(); onCleanup(() => controller.abort()); isLoading.value = true; error.value = null; try { const res = await fetch(toValue(url), { signal: controller.signal }); if (!res.ok) throw new Error(`HTTP ${res.status}`); data.value = (await res.json()) as T; } catch (e) { if ((e as Error).name !== 'AbortError') error.value = e as Error; } finally { isLoading.value = false; } }); return { data, error, isLoading }; } // ── Component usage ─────────────────────────── <script setup lang="ts"> import { ref, computed } from 'vue'; import { useFetch } from '@/composables/useFetch'; const userId = ref(1); const url = computed(() => `/api/users/${userId.value}`); const { data: user, isLoading, error } = useFetch(url); </script> <template> <p v-if="isLoading">Loading…</p> <p v-else-if="error">{{ error.message }}</p> <pre v-else>{{ user }}</pre> </template>
Result
Open