JAVASCRIPT

Building a Reusable Data Fetching Composable in Vue 3

Create a powerful and reusable custom composable in Vue 3 Composition API to handle data fetching, loading states, and error management efficiently across components.

// src/composables/useFetch.js
import { ref, 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
    data.value = null
    error.value = null

    try {
      const res = await fetch(url)
      if (!res.ok) {
        throw new Error(`HTTP error! status: ${res.status}`)
      }
      data.value = await res.json()
    } catch (e) {
      error.value = e
    } finally {
      loading.value = false
    }
  }

  watchEffect(() => {
    doFetch()
  })

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

// src/App.vue
<script setup>
import { useFetch } from './composables/useFetch'

const { data, error, loading, refetch } = useFetch('https://jsonplaceholder.typicode.com/todos/1')
</script>

<template>
  <div>
    <h1>Todo Item</h1>
    <p v-if="loading">Loading...</p>
    <p v-else-if="error">Error: {{ error.message }}</p>
    <div v-else>
      <p>ID: {{ data.id }}</p>
      <p>Title: {{ data.title }}</p>
      <p>Completed: {{ data.completed ? 'Yes' : 'No' }}</p>
    </div>
    <button @click="refetch">Refetch Data</button>
  </div>
</template>
How it works: This snippet illustrates how to create a custom composable `useFetch` to centralize data fetching logic. The `useFetch` function takes a URL, performs an asynchronous fetch request, and manages `data`, `error`, and `loading` reactive states. It uses `watchEffect` to automatically re-run the fetch when `url` changes (though not shown here, `url` could also be a ref). The `doFetch` function can also be explicitly called via `refetch`. This composable provides a clean, reusable interface for any component needing to fetch data, reducing duplication and improving maintainability. Components simply destructure the returned reactive properties to display fetched data or handle states.

Need help integrating this into your project?

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

Hire DigitalCodeLabs