The Fetch API lets your Vue component get data from the internet easily. It helps your app show fresh information without reloading the page.
Fetch API in Vue components
fetch(url) .then(response => response.json()) .then(data => { // use the data here }) .catch(error => { // handle errors here })
The fetch function returns a promise that resolves to a response object.
You usually call response.json() to get the data in JSON format.
fetch('https://api.example.com/data') .then(res => res.json()) .then(data => console.log(data))
fetch('https://api.example.com/data') .then(res => { if (!res.ok) throw new Error('Network error') return res.json() }) .then(data => console.log(data)) .catch(err => console.error(err))
This Vue component fetches user data from a public API when it loads. It shows a loading message while waiting, displays the user name and email when done, and shows an error message if something goes wrong. It uses semantic HTML and ARIA roles for accessibility.
<template>
<main>
<h1>User Info</h1>
<section aria-live="polite">
<p v-if="loading">Loading user data...</p>
<p v-if="error" role="alert" style="color: var(--error-color);">Error: {{ error }}</p>
<article v-if="user">
<h2>{{ user.name }}</h2>
<p>Email: {{ user.email }}</p>
</article>
</section>
</main>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const user = ref(null)
const loading = ref(false)
const error = ref(null)
onMounted(async () => {
loading.value = true
error.value = null
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users/1')
if (!response.ok) throw new Error('Failed to fetch user data')
user.value = await response.json()
} catch (err) {
error.value = err.message
} finally {
loading.value = false
}
})
</script>
<style scoped>
:root {
--error-color: #b00020;
}
main {
max-width: 30rem;
margin: 2rem auto;
font-family: Arial, sans-serif;
padding: 1rem;
border: 1px solid #ccc;
border-radius: 0.5rem;
}
article {
background-color: #f9f9f9;
padding: 1rem;
border-radius: 0.25rem;
}
</style>Always handle errors to avoid your app breaking if the fetch fails.
Use aria-live="polite" to announce loading or error messages to screen readers.
Keep your UI responsive by showing loading states while waiting for data.
The Fetch API helps your Vue app get data from the internet easily.
Use fetch inside lifecycle hooks like onMounted to load data when the component appears.
Show loading and error messages to keep users informed.
Practice
Solution
Step 1: Understand Fetch API role
The Fetch API is used to request data from a server or internet resource.Step 2: Connect Fetch API to Vue component
Inside Vue components, fetch is used to load data that the component will display or use.Final Answer:
To get data from the internet and use it in the component -> Option CQuick Check:
Fetch API = get data [OK]
- Thinking Fetch API styles components
- Confusing fetch with event handling
- Using fetch to create components
<script setup> component to load data on mount?Solution
Step 1: Identify lifecycle hook for data loading
onMounted() runs code after the component appears, perfect for fetching data.Step 2: Match fetch usage to lifecycle hook
Calling fetch inside onMounted() ensures data loads once component is ready.Final Answer:
Call fetch inside the onMounted() lifecycle hook -> Option AQuick Check:
Fetch in onMounted = correct usage [OK]
- Trying to fetch data in template (not allowed)
- Using computed for async fetch (wrong usage)
- Using watchEffect without dependencies causing repeated fetch
<script setup> code runs?import { ref, onMounted } from 'vue';
const data = ref(null);
const error = ref(null);
onMounted(async () => {
try {
const res = await fetch('https://jsonplaceholder.typicode.com/posts/1');
data.value = await res.json();
console.log(data.value.title);
} catch (e) {
error.value = 'Failed to load';
console.log(error.value);
}
});Solution
Step 1: Analyze fetch and await usage
The code fetches a post from the API and waits for the JSON response.Step 2: Check console.log output
It logs the title property of the fetched post, so it prints the post's title.Final Answer:
Logs the title of the post with id 1 from the API -> Option DQuick Check:
Fetch success logs title [OK]
- Assuming fetch always fails
- Thinking async is not allowed in onMounted
- Expecting undefined because of missing await
<script setup> snippet that fetches data:import { ref, onMounted } from 'vue';
const data = ref(null);
const error = ref(null);
onMounted(() => {
fetch('https://api.example.com/data')
.then(response => response.json())
.then(json => data = json)
.catch(() => error.value = 'Error fetching');
});Solution
Step 1: Check how ref is updated
Refs in Vue must be updated by setting their .value property, not the ref variable itself.Step 2: Identify incorrect assignment
The code assigns json directly to data, which breaks reactivity; it should be data.value = json.Final Answer:
Assigning json directly to data instead of data.value -> Option AQuick Check:
Update ref with .value [OK]
- Forgetting .value when setting ref
- Confusing async/await with then chaining
- Thinking onMounted is wrong lifecycle hook here
<script setup> code correctly implements fetch with loading and error states?Solution
Step 1: Check reactive state setup
const loading = ref(false); const error = ref(null); const user = ref(null); onMounted(async () => { loading.value = true; try { const res = await fetch('/user'); user.value = await res.json(); } catch { error.value = 'Failed to load user'; } finally { loading.value = false; } }); uses ref() for loading, error, and user, enabling reactivity and UI updates.Step 2: Verify fetch with loading and error handling
It sets loading true before fetch, uses try/catch for errors, and sets loading false in finally block.Final Answer:
Uses refs with onMounted, try/catch/finally for loading and error states -> Option BQuick Check:
Loading true before fetch, false after [OK]
- Not using ref for reactive state
- Setting loading false too early
- Missing error handling in async fetch
Ready to prove it?
Pass the test and this pattern moves unknown
