Quản lý trạng thái loading và error
Khi làm việc với API, việc xử lý trạng thái tải dữ liệu (loading) và lỗi (error) là rất quan trọng để đảm bảo trải nghiệm người dùng tốt. Nuxt 3 cung cấp cơ chế theo dõi tự động các trạng thái này thông qua các hook như useFetch
và useAsyncData
. Trong bài học này, bạn sẽ học cách hiển thị skeleton UI, thông báo lỗi rõ ràng, cũng như cách thử lại khi có lỗi xảy ra. Ngoài ra, bạn cũng sẽ thực hành tạo một component danh sách có xử lý loading và error thực tế.

Quản lý trạng thái loading và error
1. Theo dõi pending
, error
, data
với useAsyncData
Ví dụ cơ bản:
<script setup>
const { data, pending, error } = await useAsyncData('posts', () =>
$fetch('https://jsonplaceholder.typicode.com/posts')
)
</script>
-
pending
:true
khi đang gọi API. -
error
: chứa lỗi nếu có lỗi xảy ra. -
data
: kết quả trả về từ API.
2. Hiển thị UI loading và xử lý lỗi
<template>
<div v-if="pending">Đang tải dữ liệu...</div>
<div v-else-if="error">Lỗi: {{ error.message }}</div>
<ul v-else>
<li v-for="post in data" :key="post.id">{{ post.title }}</li>
</ul>
</template>
Cải thiện với Skeleton Loader:
<div v-if="pending" class="skeleton">Đang tải dữ liệu...</div>
3. Retry khi lỗi (thử lại thủ công)
const { data, pending, error, refresh } = await useAsyncData('posts', () =>
$fetch('/api/posts')
)
<button v-if="error" @click="refresh()">Thử lại</button>
4. Xử lý lỗi nâng cao với try-catch, createError
, showError
Ví dụ trong API backend:
export default defineEventHandler(async () => {
try {
// logic...
} catch (err) {
throw createError({ statusCode: 500, statusMessage: 'Lỗi server!' })
}
})
Ví dụ trong phía client:
try {
const data = await $fetch('/api/something')
} catch (err) {
showError({ statusCode: 400, statusMessage: 'Lỗi khi gọi API' })
}
5. Thực hành: Component danh sách có loading và error
<script setup>
const { data, pending, error, refresh } = await useFetch('/api/posts')
</script>
<template>
<div v-if="pending">Đang tải...</div>
<div v-else-if="error">
Lỗi: {{ error.message }} <br />
<button @click="refresh()">Thử lại</button>
</div>
<ul v-else>
<li v-for="post in data" :key="post.id">{{ post.title }}</li>
</ul>
</template>
Kết luận
Việc theo dõi và xử lý trạng thái loading và error là yếu tố không thể thiếu trong ứng dụng thực tế. Bài học này đã giúp bạn nắm vững cách tận dụng pending
, error
, và refresh
từ các hook như useFetch
, useAsyncData
. Bạn cũng đã biết cách hiển thị thông báo thân thiện với người dùng, thử lại khi có lỗi, và xử lý lỗi nâng cao bằng createError
và showError
. Những kỹ năng này sẽ giúp bạn xây dựng giao diện thân thiện và chuyên nghiệp hơn.

Với hơn 10 năm kinh nghiệm lập trình web và từng làm việc với nhiều framework, ngôn ngữ như PHP, JavaScript, React, jQuery, CSS, HTML, CakePHP, Laravel..., tôi hy vọng những kiến thức được chia sẻ tại đây sẽ hữu ích và thiết thực cho các bạn.
Xem thêm

Chào, tôi là Vũ. Đây là blog hướng dẫn lập trình của tôi.
Liên hệ công việc qua email dưới đây.
lhvuctu@gmail.com