JAVASCRIPT

Reusable Composable for Asynchronous Data Fetching in Vue 3

Build a robust and reusable composable function in Vue 3 to encapsulate async data fetching logic, complete with loading, error, and data states.

// composables/useFetch.js
import { ref, onMounted, watch } 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;
    try {
      const response = await fetch(urlRef.value);
      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;
    }
  }

  // Watch the urlRef for changes and re-fetch
  watch(urlRef, doFetch, { immediate: true });

  // Optionally, if you only want to fetch once on mount
  // onMounted(() => doFetch());

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

// In a Vue component (.vue file)
<template>
  <div>
    <p v-if="loading">Loading posts...</p>
    <p v-else-if="error">Error: {{ error.message }}</p>
    <ul v-else>
      <li v-for="post in data" :key="post.id">{{ post.title }}</li>
    </ul>
    <button @click="currentPostId++">Next Post Group</button>
  </div>
</template>

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

const currentPostId = ref(1);
const postUrl = computed(() => `https://jsonplaceholder.typicode.com/posts?_start=${(currentPostId.value - 1) * 5}&_limit=5`);

const { data, error, loading, refetch } = useFetch(postUrl);
</script>
How it works: This snippet demonstrates creating a reusable 'composable' in Vue 3 for fetching asynchronous data. The `useFetch` composable abstracts away the data fetching logic, including managing `loading`, `error`, and `data` states. It accepts a `urlRef` (a reactive reference to the URL) and uses `watch` with `immediate: true` to trigger the fetch operation whenever the URL changes, and also on initial component setup. Components can then easily consume this composable, separating data fetching concerns from UI logic. The `refetch` function is also returned, allowing manual trigger of the fetch operation if needed, for example, on a refresh button click.

Need help integrating this into your project?

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

Hire DigitalCodeLabs