Nuxt/docs/content/3.docs/1.usage/1.data-fetching.md
2021-10-12 14:51:41 +02:00

115 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Data Fetching
Nuxt provides `useFetch` and `useAsyncData` to handle data fetching within your application.
## `useAsyncData`
Within your pages, components and plugins you can use `useAsyncData` to get access to data that resolves asynchronously.
### Usage
```js
useAsyncData(key: string, fn: () => Object, options?: { defer: boolean, server: boolean })
```
* **key**: a unique key to ensure that data fetching can be properly de-duplicated across requests
* **fn** an asynchronous function that returns a value.
* **options**:
- _defer_: whether to load the route before resolving the async function (defaults to `false`)
- _server_: whether the fetch the data on server-side (defaults to `true`)
- _transform_: A function that can be used to alter fn result after resolving
- _pick_: Only pick specified keys in this array from fn result
Under the hood, `defer: false` uses `<Suspense>` to block the loading of the route before the data has been fetched. Consider using `defer: true` and implementing a loading state instead for a snappier user experience.
### Example
```js [server/api/count.ts]
let counter = 0
export default () => {
counter++
return JSON.stringify(counter)
}
```
```vue [app.vue]
<script setup>
const { data } = await useAsyncData('count', () => $fetch('/api/count'))
</script>
<template>
Page visits: {{ data }}
</template>
```
## `useFetch`
Within your pages, components and plugins you can use `useFetch` to get universally fetch from any URL.
This composable provides a convenient wrapper around `useAsyncData` and `$fetch` and automatically generates a key based on url and fetch options and infers API response type.
Usage:
```ts
useFetch(url: string, options?)
```
Available options:
- `key`: Provide a custom key
- Options from [ohmyfetch](https://github.com/unjs/ohmyfetch)
- `method`: Request method
- `params`: Query params
- `baseURL`: Base URL for request
- Options from `useAsyncDaa`
- `defer`
- `server`
- `pick`
- `transform`
### Example
```vue [app.vue]
<script setup>
const { data } = await useFetch('/api/count')
</script>
<template>
Page visits: {{ data.count }}
</template>
```
### Best practices
As seen in [Concepts > Data fetching](/concepts/data-fetching), the data returned by `useAsyncData` will be stored inside the page payload. This mean that every key returned that is not used in your component will be added to the payload.
**We strongly recommend to only select the keys that you will use in your component.**
Imagine that `/api/mountains/everest` returns the following object:
```json
{
"title": "Mount Everest",
"description": "Mount Everest is Earth's highest mountain above sea level, located in the Mahalangur Himal sub-range of the Himalayas. The ChinaNepal border runs across its summit point",
"height": "8,848 m",
"countries": [
"China",
"Nepal"
],
"continent": "Asia",
"image": "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Everest_kalapatthar.jpg/600px-Everest_kalapatthar.jpg"
}
```
If you plan to only use `title` and `description` in your component, you can select the keys by chaining the result of `$fetch` or `pick` option:
```vue
<script setup>
const { data: mountain } = await useFetch('/api/mountains/everest', { pick: ['title', 'description'] })
</script>
<template>
<h1>{{ mountain.title }}</h1>
<p>{{ mountain.description }}</p>
</template>
```