JAVASCRIPT

Reusable Vue 3 Composable for API Data Fetching

Create a custom Vue 3 composable (`useFetch`) to handle asynchronous data fetching, including loading, error, and data states, making API calls reusable and organized.

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

export function useFetch(url, options = {}) {
  const data = ref(null);
  const error = ref(null);
  const loading = ref(true);

  const fetchData = async () => {
    loading.value = true;
    error.value = null;
    try {
      const res = await fetch(url, options);
      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;
    }
  };

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

  // Optional: re-fetch if URL or options change
  // For more robust dependency tracking for options, consider a deep watch on `options`
  // watchEffect(() => fetchData()); // Would refetch on any reactive change in dependencies

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

// Usage in a Vue component:
/*
<template>
  <div>
    <h1>Posts</h1>
    <div v-if="loading">Loading posts...</div>
    <div v-else-if="error">Error: {{ error.message }}</div>
    <ul v-else>
      <li v-for="post in data" :key="post.id">{{ post.title }}</li>
    </ul>
    <button @click="refetch">Refetch Posts</button>
  </div>
</template>

<script setup>
import { useFetch } from './composables/useFetch'; // Adjust path as needed

const { data, error, loading, refetch } = useFetch('https://jsonplaceholder.typicode.com/posts?_limit=5');
</script>
*/
How it works: This `useFetch` composable simplifies data fetching in Vue 3 applications. It encapsulates the logic for making an API request, managing `loading`, `error`, and `data` states using Vue's `ref`. The `fetchData` function performs the actual request, updating these reactive states accordingly. `onMounted` ensures the data is fetched when the component is first mounted. This pattern promotes code reusability, keeping component logic clean and focusing on presentation concerns rather than data fetching boilerplate.

Need help integrating this into your project?

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

Hire DigitalCodeLabs