Roadmap › Vue.js 3 (with Pinia, Vue Router & Nuxt basics) › Module: Components
Lessons in this course (17)
10. Composables (reusable logic)
Intermediate★ Must knowLesson 10 of 17
ts
// 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 loading = ref(false);
watchEffect(async onCleanup => {
const controller = new AbortController();
onCleanup(() => controller.abort());
loading.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();
} catch (e) {
if ((e as Error).name !== "AbortError") error.value = e as Error;
} finally {
loading.value = false;
}
});
return { data, error, loading };
}
// In a component
const { data: orders, loading } = useFetch<Order[]>(() => `/api/orders?page=${page.value}`);Composables are functions named useXxx that use Composition API features; each call gets its own state (or share module-level state for a singleton). VueUse offers 200+ ready-made composables (useLocalStorage, useDebounceFn, useIntersectionObserver).