JAVASCRIPT
Vue 3 Composable for Asynchronous Data Fetching
Build a reusable Vue 3 Composable to handle asynchronous data fetching, loading states, and error handling, promoting cleaner and more modular code.
// composables/useFetch.js
import { ref, onMounted, toValue } from 'vue';
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const loading = ref(true);
async function fetchData() {
loading.value = true;
error.value = null;
try {
const res = await fetch(toValue(url));
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`);
}
data.value = await res.json();
} catch (err) {
error.value = err;
} finally {
loading.value = false;
}
}
onMounted(() => {
fetchData();
});
return { data, error, loading, refetch: fetchData };
}
// App.vue (or any component)
<template>
<div>
<h1>User Data</h1>
<p v-if="loading">Loading...</p>
<p v-else-if="error">Error: {{ error.message }}</p>
<div v-else>
<p>Name: {{ data.name }}</p>
<p>Email: {{ data.email }}</p>
<button @click="refetch">Refetch Data</button>
</div>
</div>
</template>
<script setup>
import { useFetch } from './composables/useFetch';
const { data, error, loading, refetch } = useFetch('https://jsonplaceholder.typicode.com/users/1');
</script>
How it works: This Vue 3 composable, `useFetch`, encapsulates the logic for fetching data from an API, managing loading states, and handling errors. It leverages `ref` for reactive state, `onMounted` to initiate the fetch, and `toValue` to handle dynamic URLs. By returning `data`, `error`, `loading`, and `refetch`, components can easily consume this reusable logic, promoting cleaner and more modular code for data retrieval.