JAVASCRIPT
Creating a Reusable Vue 3 Composable for Fetching Data
Discover how to build a custom Composition API function (composable) in Vue 3 to encapsulate and reuse data fetching logic across multiple components.
// src/composables/useFetch.js
import { ref, isRef, unref, watchEffect } from 'vue';
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const loading = ref(true);
async function doFetch() {
// reset state before fetching..
data.value = null;
error.value = null;
loading.value = true;
// resolve the url value if it is a ref
const urlValue = unref(url);
try {
const res = await fetch(urlValue);
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`);
}
data.value = await res.json();
} catch (e) {
error.value = e;
} finally {
loading.value = false;
}
}
if (isRef(url)) {
// setup reactive re-fetch if url is a ref
watchEffect(doFetch);
} else {
// otherwise, just fetch once
doFetch();
}
return { data, error, loading, doFetch };
}
// src/App.vue (example usage)
<template>
<div>
<h1>User List</h1>
<p v-if="loading">Loading users...</p>
<p v-else-if="error">Error: {{ error.message }}</p>
<ul v-else-if="data">
<li v-for="user in data" :key="user.id">{{ user.name }} ({{ user.email }})</li>
</ul>
<button @click="refreshUsers">Refresh Users</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useFetch } from './composables/useFetch';
const userId = ref(1);
const usersUrl = ref('https://jsonplaceholder.typicode.com/users');
// Example of using a reactive URL
// const userDetailUrl = computed(() => `https://jsonplaceholder.typicode.com/users/${userId.value}`);
const { data, error, loading, doFetch: refreshUsers } = useFetch(usersUrl);
// You could also use the composable with a static URL
// const { data: posts, error: postsError, loading: postsLoading } = useFetch('https://jsonplaceholder.typicode.com/posts');
// Example of changing the URL reactivity
// setTimeout(() => { userId.value = 2; }, 3000);
</script>
How it works: This snippet defines `useFetch`, a custom composable (Composition API function) for fetching data from an API. It encapsulates reactive state (`data`, `error`, `loading`) and the `doFetch` logic. The `unref` utility ensures that if the `url` argument is a ref, its value is accessed. `watchEffect` is used to automatically re-run `doFetch` whenever the `url` (if it's a ref) changes, making the composable reactive. This pattern promotes code reuse, cleaner components, and better separation of concerns.