JAVASCRIPT

Create a Reusable Data Fetching Composable

Build a custom Vue 3 Composition API composable (`useFetch`) to encapsulate data fetching logic, including loading and error states, for reuse across components, simplifying API calls.

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

export function useFetch(url) {
  const data = ref(null);
  const error = ref(null);
  const isLoading = ref(true);

  async function doFetch() {
    isLoading.value = true;
    error.value = null;
    try {
      const response = await fetch(toValue(url));
      if (!response.ok) {
        throw new Error(`HTTP error! Status: ${response.status}`);
      }
      data.value = await response.json();
    } catch (err) {
      error.value = err.message || 'An unknown error occurred.';
    } finally {
      isLoading.value = false;
    }
  }

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

  return { data, error, isLoading, doFetch };
}

// src/App.vue (Usage)
<template>
  <div>
    <h1>Data Fetching Composable Example</h1>
    <button @click="doFetch" :disabled="isLoading">Refetch Data</button>

    <div v-if="isLoading">
      <p>Loading posts...</p>
    </div>
    <div v-else-if="error">
      <p style="color: red;">Error: {{ error }}</p>
    </div>
    <div v-else>
      <h2>Posts</h2>
      <ul>
        <li v-for="post in data.slice(0, 5)" :key="post.id">
          <strong>{{ post.title }}</strong>
          <p>{{ post.body.substring(0, 50) }}...</p>
        </li>
      </ul>
    </div>
  </div>
</template>

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

const { data, error, isLoading, doFetch } = useFetch('https://jsonplaceholder.typicode.com/posts');

// Optionally, react to changes in a reactive URL or trigger refetch
// watch(someReactiveUrl, doFetch);
</script>
How it works: This snippet provides a `useFetch` composable for Vue 3 that encapsulates asynchronous data fetching logic. It manages `data`, `error`, and `isLoading` reactive states, making it easy to display UI feedback during different stages of a request. The `onMounted` hook triggers the initial fetch, and a `doFetch` function is returned to allow manual refetching. `toValue` ensures that the URL can be either a static string or a reactive ref/computed property. This composable promotes reusability and keeps component logic clean by abstracting away common data fetching patterns.

Need help integrating this into your project?

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

Hire DigitalCodeLabs