JAVASCRIPT
Creating a Reusable Composable for Asynchronous Data Fetching
Learn to build a custom Vue 3 composable to encapsulate data fetching logic, providing reactive state for loading, error, and data, promoting code reuse.
// composables/useFetch.js
import { ref, watchEffect, toValue } from 'vue';
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const loading = ref(true);
watchEffect(async () => {
// reset state before fetching
data.value = null;
error.value = null;
loading.value = true;
try {
const response = await fetch(toValue(url));
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
data.value = await response.json();
} catch (e) {
error.value = e;
} finally {
loading.value = false;
}
});
return { data, error, loading };
}
// In a Vue component (e.g., MyComponent.vue)
<template>
<div>
<h1>Posts</h1>
<p v-if="loading">Loading posts...</p>
<p v-if="error">Error: {{ error.message }}</p>
<ul v-if="data">
<li v-for="post in data" :key="post.id">{{ post.title }}</li>
</ul>
</div>
</template>
<script setup>
import { useFetch } from './composables/useFetch';
const { data, error, loading } = useFetch('https://jsonplaceholder.typicode.com/posts');
</script>
How it works: This snippet demonstrates how to create a custom composable, `useFetch`, for abstracting asynchronous data fetching logic in Vue 3. It utilizes `ref` for reactive state (`data`, `error`, `loading`) and `watchEffect` to automatically re-fetch data whenever the URL changes. This promotes reusability and clean separation of concerns, making data fetching manageable across multiple components.