Data Fetch
Nuxt의 문서에서 Data Fetch와 관련한 문서를 보면$fetch / useAsyncData / useFetch 로 나누어져 있다.
<script setup lang="ts">
// SSR 동안 데이터는 서버에서 한 번, 클라이언트에서 한 번, 총 두 번 가져옵니다.
const dataTwice = await $fetch('/api/item')
// SSR 중에는 데이터가 서버 측에서만 가져와 클라이언트로 전송됩니다.
const { data } = await useAsyncData('item', () => $fetch('/api/item'))
//useAsyncData + $fetch의 바로가기로 Fetch를 사용할 수도 있습니다.
const { data } = await useFetch('/api/item')
</script>
$fetch
(https://nuxt.com/docs/api/utils/dollarfetch)
$fetch는 클라이언트 측에서만 실행되는 모든 메소드에 사용할 수 있습니다 .
또한 useAsyncData로 래핑하지 않고 구성 요소에서 $fetch를 사용하면 데이터를 두 번 가져오게 됩니다.
처음에는 서버에서, 그 다음에는 하이드레이션 중에 클라이언트 측에서 다시 가져옵니다.
$fetch가 서버에서 클라이언트로 상태를 전송하지 않기 때문입니다.
따라서 클라이언트가 데이터를 다시 가져와야 하므로 가져오기는 양쪽에서 실행됩니다.
클라이언트 측에서만 실행되는 모든 메소드에 사용할 수 있다.
// ./page/contact.vue
<script setup lang="ts">
function contactForm() {
$fetch('/api/contact', {
method: 'POST',
body: { hello: 'world '}
})
}
</script>
<template>
<button @click="contactForm">Contact</button>
</template>
$fetchNuxt 2용으로 만들어진 @nuxt/http 및 @nuxtjs/axios 대신 Nuxt에서 HTTP 호출을 수행하는 데 선호되는 방법입니다 .
useAsyncData
(https://nuxt.com/docs/api/composables/use-async-data)
useAsyncData는 SSR 친화적인 컴포저블에서 비동기적으로 확인되는 데이터에 대한 액세스를 제공합니다.
페이지, 컴포넌트 및 플러그인 내에서 useAsyncData를 사용하여 비동기적으로 확인되는 데이터에 액세스할 수 있습니다.
<script setup>
const { data, pending, error, refresh } = await useAsyncData(
'mountains',
() => $fetch('https://api.nuxtjs.dev/mountains')
)
</script>
Watch 매개변수
내장 watch옵션을 사용하면 변경 사항이 감지되면 페처 기능을 자동으로 다시 실행할 수 있습니다.
<script setup>
const page = ref(1)
const { data: posts } = await useAsyncData(
'posts',
() => $fetch('https://fakeApi.com/posts', {
params: {
page: page.value
}
}), {
watch: [page]
}
)
</script>
매개변수
key: 데이터 가져오기가 요청 전반에 걸쳐 적절하게 중복 제거될 수 있도록 보장하는 고유 키입니다. 키를 제공하지 않으면 의 인스턴스 행 번호와 파일 이름에 고유한 키가 useAsyncData생성됩니다.
handler: 실제 값을 반환해야 하는 비동기 함수(예: undefined 또는 null 이면 안 됨). 그렇지 않으면 요청이 클라이언트 측에서 중복될 수 있습니다.
options:
- server: 서버에서 데이터를 가져올지 여부 (기본값은 true)
- lazy: 클라이언트 측 탐색을 차단하는 대신 경로를 로드한 후 비동기 기능을 해결할지 여부(기본값은 false)
- immediate: false로 설정하면 요청이 즉시 실행되지 않습니다. (기본값은 true)
- defaultdata: 비동기 함수가 해결되기 전에 의 기본값을 설정하는 팩토리 함수 - lazy: true or immediate: false옵션 과 함께 유용함
- transform handler: 해결 후 함수 결과를 변경하는 데 사용할 수 있는 함수
- pick handler: 함수 결과 에서 이 배열의 지정된 키만 선택합니다.
- watch: 자동 새로고침을 위해 반응 소스를 관찰합니다.
- deep: 깊은 참조 객체의 데이터를 반환합니다(기본값 true). false얕은 참조 객체에 데이터를 반환하도록 설정할 수 있으며 , 이는 데이터가 깊게 반응할 필요가 없는 경우 성능을 향상시킬 수 있습니다.
useFetch
(https://nuxt.com/docs/api/composables/use-fetch)
SSR 친화적인 컴포저블을 사용하여 API 엔드포인트에서 데이터를 가져옵니다.
이 컴포저블은 AsyncData와 $fetch를 사용하는 데 편리한 wrapper를 제공합니다.
URL 및 fetch 옵션을 기반으로 키를 자동으로 생성하고 서버 경로를 기반으로 요청 URL에 대한 유형 힌트를 제공하며 API 응답 유형을 추론합니다.
useFetch는 설정 기능, 플러그인 또는 경로 미들웨어에서 직접 호출할 수 있는 합성 파일입니다. 이것은 반응형 컴포저블을 반환하고 Nuxt 페이로드에 응답을 추가하는 작업을 처리하여 페이지가 렌더링간의 조화를 공급할 때 클라이언트 측의 데이터를 다시 가져오지 않고 서버에서 클라이언트로 전달할 수 있습니다.
<script setup>
const route = useRoute()
const { data, pending, error, refresh } = await useFetch(`https://api.nuxtjs.dev/mountains/${route.params.slug}`, {
pick: ['title']
})
</script>
query를 사용해 fetching을 확장시킬수 있습니다.
const param1 = ref('value1')
const { data, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains', {
query: { param1, param2: 'value2' }
})
// https://api.nuxtjs.dev/mountains?param1=value1¶m2=value2
Interceptors 사용이 가능하다
const { data, pending, error, refresh } = await useFetch('/api/auth/login', {
onRequest({ request, options }) {
// Set the request headers
options.headers = options.headers || {}
options.headers.authorization = '...'
},
onRequestError({ request, options, error }) {
// Handle the request errors
},
onResponse({ request, response, options }) {
// Process the response data
localStorage.setItem('token', response._data.token)
},
onResponseError({ request, response, options }) {
// Handle the response errors
}
})
커스텀fetch 관련(https://nuxt.com/docs/examples/advanced/use-custom-fetch-composable)
매개변수
URL: 가져올 URL입니다.
Options( unjs/ofetch 옵션 및 AsyncDataOptions 확장 ):
모든 fetch option에는 computed와 ref의 값을 줄 수 있다. 이를 감시하고 업데이트된 경우 새 값으로 자동으로 새 요청이 수행된다.
options: useAsyncData의 옵션을 사용할수 있다.
- server: 서버에서 데이터를 가져올지 여부 (기본값은 true)
- lazy: 클라이언트 측 탐색을 차단하는 대신 경로를 로드한 후 비동기 기능을 해결할지 여부(기본값은 false)
- immediate: false로 설정하면 요청이 즉시 실행되지 않습니다. (기본값은 true)
- defaultdata: 비동기 함수가 해결되기 전에 의 기본값을 설정하는 팩토리 함수 - lazy: true or immediate: false옵션 과 함께 유용함
- transform handler: 해결 후 함수 결과를 변경하는 데 사용할 수 있는 함수
- pick handler: 함수 결과 에서 이 배열의 지정된 키만 선택합니다.
- watch: 자동 새로고침을 위해 반응 소스를 관찰합니다.
- deep: 깊은 참조 객체의 데이터를 반환합니다(기본값 true). false얕은 참조 객체에 데이터를 반환하도록 설정할 수 있으며 , 이는 데이터가 깊게 반응할 필요가 없는 경우 성능을 향상시킬 수 있습니다.
//동일 문
const {data: items} = await useFetch('/api/params')
const {pending, data: items} = useFetch('/api/params',{
lazy: false
server: false // 클라이언트 사이드 렌더링 이 됨
})
const {pending, data: items} = await useLazyFetch('/api/params')
Transform Handler
const {data: items} = useFetch('/api/params',
{
lazy:false,
transform:(items)=>{
return items.map((item) => ({
id: item.id
title: item.title
image: item.image
}));
}
}
)
Pick Handler
const {data: items} = useFetch('/api/params',
{
lazy:false,
pick:['id','title','image]
)
useAsyncData & useFetch 의 반환값
반환 값
- data: 전달된 비동기 함수의 결과입니다.
- pending: 데이터를 아직 가져오는 중인지 여부를 나타내는 부울입니다.
- refresh/ execute: 함수에서 반환된 데이터를 새로 고치는 데 사용할 수 있는 함수입니다 handler.
- error: 데이터 가져오기에 실패한 경우 오류 개체입니다.
- status: 데이터 요청 상태를 나타내는 문자열( "idle", "pending", "success", "error").
- 기본적으로 Nuxt는 refresh가 다시 실행되기 전에 완료될 때까지 기다립니다.
<script setup>
const param1 = ref('value1')
const { data:items, pending, error, refresh } = await useFetch('https://api.nuxtjs.dev/mountains', {
query: { param1, param2: 'value2' }
})
</script>
<template>
<div v-if="pending">
<p>로딩중</p>
</div>
<div v-else-if="error">
<p>Error Code {{ error?.message }}</p>
</div>
<div v-else>
<button @click="refresh"> 새로고침 </button>
<div>
<div v-for="item in items" :key="item.id">
{{item}}
</div>
</div>
</div>
</template>
다중 Fetching
<script setup lang="ts">
const {
pending,
data: productInfo,
refresh,
} = useAsyncData(
"productInfo",
async () => {
const [products, catagories]: any = await Promise.all([
$fetch("/api/products"),
$fetch("/api/products/categories"),
]);
return {
products,
catagories,
};
},
{
lazy: false,
transform: (productInfo) => {
return {
catagories: productInfo.catagories,
products: productInfo.products.map((product: any) => ({
id: product.id,
title: product.title,
image: product.image,
})),
};
},
}
);
</script>