JAVASCRIPT

Creating a Reusable Composable for Async Data Fetching in Vue 3

Learn to build a custom Vue 3 composable for abstracting asynchronous data fetching logic, making your components cleaner and promoting code reusability.

// composables/useFetch.js
import { ref, onMounted, toValue } from 'vue';

export function useFetch(urlRef) {
  const data = ref(null);
  const error = ref(null);
  const loading = ref(true);

  async function doFetch() {
    loading.value = true;
    error.value = null;
    data.value = null; // Clear previous data
    try {
      const response = await fetch(toValue(urlRef));
      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;
    }
  }

  onMounted(() => {
    doFetch();
  });

  // Optionally, add a watcher if urlRef is reactive and you want to refetch on change
  // import { watch } from 'vue';
  // watch(urlRef, doFetch, { deep: true });

  return { data, error, loading, refetch: doFetch };
}

// SomeComponent.vue
<template>
  <div>
    <h1>User Data</h1>
    <p v-if="loading">Loading user data...</p>
    <p v-else-if="error">Error: {{ error.message }}</p>
    <div v-else-if="data">
      <p>Name: {{ data.name }}</p>
      <p>Email: {{ data.email }}</p>
      <button @click="refetch">Refetch Data</button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { useFetch } from './composables/useFetch';

const userId = ref(1); // Example reactive URL part
const userUrl = ref(`https://jsonplaceholder.typicode.com/users/${userId.value}`);

// In a real app, userUrl might be a computed property based on userId
// const userUrl = computed(() => `https://jsonplaceholder.typicode.com/users/${userId.value}`);

const { data, error, loading, refetch } = useFetch(userUrl);

// To change user dynamically (example)
// setTimeout(() => {
//   userId.value = 2; // This would require the watch in useFetch to trigger refetch
//   userUrl.value = `https://jsonplaceholder.typicode.com/users/${userId.value}`;
// }, 3000);
</script>
How it works: This snippet demonstrates how to create a custom Vue 3 composable, `useFetch`, for encapsulating asynchronous data fetching logic. The composable manages loading, error, and data states using `ref`. It performs a fetch request when the component mounts (`onMounted`) and returns reactive references to `data`, `error`, `loading`, and a `refetch` function. The component then simply calls `useFetch` to integrate this logic, keeping its template clean and its script focused on component-specific concerns, promoting reusability across different parts of the application.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs