Fetching data is one of the most common tasks in any Vue application. This guide covers the most practical patterns.
<script setup>
import { ref, onMounted } from 'vue'
const users = ref([])
const loading = ref(false)
const error = ref(null)
onMounted(async () => {
loading.value = true
try {
const res = await fetch('https://jsonplaceholder.typicode.com/users')
users.value = await res.json()
} catch (e) {
error.value = e.message
} finally {
loading.value = false
}
})
</script>
npm install axios
// src/api/axios.js
import axios from 'axios'
export default axios.create({
baseURL: import.meta.env.VITE_API_URL,
headers: { 'Content-Type': 'application/json' },
})
// Add auth token interceptor
api.interceptors.request.use((config) => {
const token = localStorage.getItem('token')
if (token) config.headers.Authorization = `Bearer ${token}`
return config
})
// composables/useFetch.js
import { ref, watchEffect } from 'vue'
export function useFetch(urlRef) {
const data = ref(null)
const loading = ref(false)
const error = ref(null)
watchEffect(async () => {
loading.value = true
error.value = null
try {
const res = await fetch(unref(urlRef))
data.value = await res.json()
} catch (e) {
error.value = e.message
} finally {
loading.value = false
}
})
return { data, loading, error }
}
<script setup>
import { computed, ref } from 'vue'
import { useFetch } from '@/composables/useFetch'
const page = ref(1)
const url = computed(() => `/api/posts?page=${page.value}`)
const { data: posts, loading } = useFetch(url)
</script>
All Comments