JAVASCRIPT

Custom Composable for Asynchronous Data Fetching in Vue 3

Create a reusable Vue 3 composable to encapsulate asynchronous data fetching logic, providing reactive loading, error, and data states for any API request.

// 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() {
    loading.value = true;
    error.value = null;
    data.value = null;

    // unref() to get the raw value of 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 (err) {
      error.value = err;
    } 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, refetch: doFetch };
}

// src/App.vue (or any component)
<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>
    <button @click="refetch">Refetch Posts</button>
  </div>
</template>

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

const postId = ref(1);
const url = ref(`https://jsonplaceholder.typicode.com/posts?_limit=5`);

// Example usage with a reactive URL
const { data, error, loading, refetch } = useFetch(url);

// You could also change the URL reactively:
// setTimeout(() => {
//   url.value = 'https://jsonplaceholder.typicode.com/posts?_limit=10';
// }, 3000);
</script>
How it works: This composable `useFetch` abstracts away the common pattern of fetching data, managing loading states, and handling errors. It takes a URL (which can be a reactive ref) and returns `data`, `error`, and `loading` reactive references. If the URL is reactive, `watchEffect` automatically re-fetches data when the URL changes. The `refetch` function provides a way to manually trigger a re-fetch, making this a highly flexible solution for data retrieval.

Need help integrating this into your project?

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

Hire DigitalCodeLabs