1.使用Fetch
<script setup lang="ts">
interface Post {
id: string
title: string
content: string
}
// Basic usage — SSR-friendly
const { data: posts, status, error, refresh } = await useFetch<Post[]>('/api/posts')
// With options
const { data: post } = await useFetch<Post>(`/api/posts/${slug}`, {
pick: ['title', 'content'], // Only transfer these fields
transform: (data) => ({
...data,
title: data.title.toUpperCase(),
}),
})
// With query params
const page = ref(1)
const { data } = await useFetch('/api/posts', {
query: { page, limit: 10 }, // Reactive — auto-refetch
watch: [page], // Watch for changes
})
</script>
<template>
<div v-if="status === 'pending'">Loading...</div>
<div v-else-if="error">Error: {{ error.message }}</div>
<div v-else>
<div v-for="post in posts" :key="post.id">{{ post.title }}</div>
<button @click="refresh()">Refresh</button>
</div>
</template>
2.使用非同步數據
<script setup lang="ts">
// Khi cần custom fetching logic
const { data: user } = await useAsyncData('user', () => {
return $fetch('/api/user/me')
})
// Multiple parallel fetches
const [{ data: posts }, { data: categories }] = await Promise.all([
useFetch('/api/posts'),
useFetch('/api/categories'),
])
// Cached key — dedup requests
const { data } = await useAsyncData(
`post-${slug}`, // Unique key
() => $fetch(`/api/posts/${slug}`),
{ dedupe: 'cancel' } // Cancel previous request
)
</script>
3. 惰性獲取
<script setup lang="ts">
// useLazyFetch — không block navigation, render ngay
const { data, pending } = useLazyFetch('/api/posts')
// useLazyAsyncData
const { data: comments, pending: loadingComments } = useLazyAsyncData(
'comments',
() => $fetch(`/api/posts/${slug}/comments`)
)
</script>
<template>
<div>
<div v-if="pending">Loading posts...</div>
<div v-else v-for="post in data" :key="post.id">{{ post.title }}</div>
<!-- Comments load separately -->
<div v-if="loadingComments">Loading comments...</div>
<div v-else v-for="c in comments" :key="c.id">{{ c.text }}</div>
</div>
</template>
4. 渲染模式
| 模式 | 描述 | 配置 |
|---|---|---|
| 固態繼電器 | 伺服器端渲染(預設) | ssr: 正確 |
| 企業社會責任 | 僅限客戶端 | ssr: 假 |
| SSG | 靜態站點生成 | npx nuxi 生成 |
| 情報監視與偵察 | 增量靜態+重新驗證 | 路線規則 |
| 駐波比 | 重新驗證時過時 | 路線規則 |
// nuxt.config.ts — Hybrid rendering
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true }, // SSG
'/blog/**': { isr: 3600 }, // ISR — revalidate 1h
'/dashboard/**': { ssr: false }, // CSR only
'/api/**': { cors: true }, // API CORS
'/admin/**': { ssr: false, robots: false }, // CSR + no index
},
})
5. $fetch — 直接 HTTP
// $fetch — dùng trong event handlers, không trong setup
async function deletePost(id: string) {
await $fetch(`/api/posts/${id}`, {
method: 'DELETE',
})
await refreshNuxtData('posts') // Refresh cached data
}
// POST
const result = await $fetch('/api/posts', {
method: 'POST',
body: { title: 'New Post', content: '...' },
})
下一篇: Nitro 伺服器引擎和 API 路由 — 伺服器路由、中間件、資料庫。