useFetch

Исходный код
Получение данных из эндпоинта API с помощью SSR-композабла.

Этот композабл — удобная обёртка над useAsyncData и $fetch. Он сам строит ключ из URL и параметров запроса, подсказывает типы для URL по серверным маршрутам и выводит тип ответа API.

useFetch вызывают напрямую в setup, плагине или прослойке маршрута (middleware). Он возвращает реактивные ссылки и кладёт ответ в payload Nuxt, чтобы при гидратации не запрашивать те же данные на клиенте повторно.

Использование

pages/modules.vue
<script setup lang="ts">
const { data, status, error, refresh, clear } = await useFetch('/api/modules', {
  pick: ['title'],
})
</script>
Если вы используете собственную обёртку над useFetch, не используйте await внутри неё — это может дать непредсказуемое поведение. См. рецепт про пользовательский useFetch/useAsyncData.
data, status и error — это ref из Vue; к ним следует обращаться через .value внутри <script setup>, а refresh/execute и clear — обычные функции.

Используя свойство query, вы можете добавить параметры поиска в запрос. Эта опция расширена из unjs/ofetch и использует unjs/ufo для создания URL. Объекты автоматически превращаются в строку.

const param1 = ref('value1')
const { data, status, error, refresh } = await useFetch('/api/modules', {
  query: { param1, param2: 'value2' },
})

В результате приведённого выше примера получится https://api.nuxt.com/modules?param1=value1&param2=value2.

Вы также можете использовать перехватчики:

const { data, status, error, refresh, clear } = await useFetch('/api/auth/login', {
  onRequest ({ request, options }) {
    // Устанавливает заголовки запроса
    // нужен ofetch >= 1.4.0 — при необходимости обновите lockfile
    options.headers.set('Authorization', '...')
  },
  onRequestError ({ request, options, error }) {
    // Обрабатывает ошибки запроса
  },
  onResponse ({ request, response, options }) {
    // Обрабатывает данные ответа
    localStorage.setItem('token', response._data.token)
  },
  onResponseError ({ request, response, options }) {
    // Обрабатывает ошибки ответа
  },
})

Реактивный URL и общее состояние

URL может быть computed, обычным ref или функцией — данные обновятся при смене адреса:

pages/[id].vue
<script setup lang="ts">
const route = useRoute()
const id = computed(() => route.params.id)

// При смене маршрута и обновлении id данные перезапросятся автоматически
const { data: post } = await useFetch(() => `/api/posts/${id.value}`)
</script>

При одинаковом URL и опциях в нескольких компонентах общие data, error и status — состояние согласовано между ними.

Состояние с ключом из useFetch доступно в приложении через useNuxtData.
useFetch — зарезервированное имя, которое обрабатывает компилятор; свою функцию так называть нельзя.
Если вы столкнулись с тем, что переменная data, деструктурированная из useFetch, возвращает строку, а не разобранный JSON-объект, убедитесь, что ваш компонент не включает оператор импорта, подобный import { useFetch } from '@vueuse/core'.
Узнать больше Docs > 3 X > Getting Started > Data Fetching.

Реактивные опции запроса

Опции запроса могут быть реактивными: computed, ref и вычисляемые геттеры. При изменении реактивной опции выполняется повторный запрос с актуальным значением.

const searchQuery = ref('initial')
const { data } = await useFetch('/api/search', {
  query: { q: searchQuery },
})
// повторный запрос: /api/search?q=new%20search
searchQuery.value = 'new search'

Отключить это поведение можно через watch: false:

const searchQuery = ref('initial')
const { data } = await useFetch('/api/search', {
  query: { q: searchQuery },
  watch: false,
})
// повторного запроса не будет
searchQuery.value = 'new search'

Тип

Signature
export function useFetch<DataT, ErrorT> (
  url: string | Request | Ref<string | Request> | (() => string | Request),
  options?: UseFetchOptions<DataT>,
): Promise<AsyncData<DataT, ErrorT>>

type UseFetchOptions<DataT> = {
  key?: MaybeRefOrGetter<string>
  method?: MaybeRefOrGetter<string>
  query?: MaybeRefOrGetter<SearchParams>
  params?: MaybeRefOrGetter<SearchParams>
  body?: MaybeRefOrGetter<RequestInit['body'] | Record<string, any>>
  headers?: MaybeRefOrGetter<Record<string, string> | [key: string, value: string][] | Headers>
  baseURL?: MaybeRefOrGetter<string>
  cache?: false | 'default' | 'force-cache' | 'no-cache' | 'no-store' | 'only-if-cached' | 'reload'
  server?: boolean
  lazy?: boolean
  immediate?: boolean
  getCachedData?: (key: string, nuxtApp: NuxtApp, ctx: AsyncDataRequestContext) => DataT | undefined
  deep?: boolean
  dedupe?: 'cancel' | 'defer'
  timeout?: number
  default?: () => DataT
  transform?: (input: DataT) => DataT | Promise<DataT>
  pick?: string[]
  $fetch?: typeof globalThis.$fetch
  watch?: MultiWatchSources | false
  timeout?: MaybeRefOrGetter<number>
}

type AsyncDataRequestContext = {
  /** Причина этого запроса данных */
  cause: 'initial' | 'refresh:manual' | 'refresh:hook' | 'watch'
}

type AsyncData<DataT, ErrorT> = {
  data: Ref<DataT | null>
  pending: Ref<boolean>
  refresh: (opts?: AsyncDataExecuteOptions) => Promise<void>
  execute: (opts?: AsyncDataExecuteOptions) => Promise<void>
  clear: () => void
  error: Ref<ErrorT | null>
  status: Ref<AsyncDataRequestStatus>
}

interface AsyncDataExecuteOptions {
  dedupe?: 'cancel' | 'defer'
  timeout?: number
  signal?: AbortSignal
}

type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error'

Параметры

  • URL (string | Request | Ref<string | Request> | () => string | Request): URL или объект Request. Может быть строкой, Request, ref Vue или функцией; поддерживается реактивность.
  • options (object): настройки запроса. Расширяет unjs/ofetch и AsyncDataOptions. Любая опция может быть константой, ref или computed.
ОпцияТипПо умолчаниюОписание
keyMaybeRefOrGetter<string>автоУникальный ключ дедупликации; если не задан — из URL и опций.
methodstring'GET'HTTP-метод.
queryobject-Параметры строки запроса. Псевдоним: params. Поддержка ref/computed.
paramsobject-То же, что query.
bodyRequestInit['body'] | Record<string, any>-Тело запроса; объекты сериализуются. Поддержка ref/computed.
headersRecord<string, string> | [key, value][] | Headers-Заголовки.
baseURLstring-Базовый URL.
timeoutnumber-Таймаут в мс до отмены запроса.
cacheboolean | string-Кэш: false отключает или значения Fetch API: default, no-store и т.д.
serverbooleantrueВыполнять ли запрос на сервере.
lazybooleanfalseПри true — после загрузки маршрута (не блокирует навигацию).
immediatebooleantrueПри false запрос не стартует сразу.
default() => DataT-Значение data до завершения асинхронной части.
transform(input: DataT) => DataT | Promise<DataT>-Преобразование результата после получения.
getCachedData(key, nuxtApp, ctx) => DataT | undefined-Возврат кэшированных данных; см. значение по умолчанию ниже.
pickstring[]-Оставить в результате только перечисленные ключи.
watchMultiWatchSources | false-Реактивные источники для автообновления; false отключает.
deepbooleanfalseГлубокий ref; при false — поверхностный (shallow), быстрее, если глубокая реактивность не нужна.
dedupe'cancel' | 'defer''cancel'Не дублировать запросы с одним ключом.
$fetchtypeof globalThis.$fetch-Своя реализация $fetch.
Любую опцию можно задать через computed или ref — при изменении выполнится новый запрос.

Значение getCachedData по умолчанию:

const getDefaultCachedData = (key, nuxtApp, ctx) => nuxtApp.isHydrating
  ? nuxtApp.payload.data[key]
  : nuxtApp.static.data[key]

Кэширование срабатывает только при включённом experimental.payloadExtraction в nuxt.config.

Возвращаемое значение

ИмяТипОписание
dataRef<DataT | undefined>Результат асинхронного запроса.
refresh(opts?: AsyncDataExecuteOptions) => Promise<void>Ручное обновление. По умолчанию Nuxt ждёт завершения текущего refresh перед следующим вызовом.
execute(opts?: AsyncDataExecuteOptions) => Promise<void>Синоним refresh.
errorRef<ErrorT | undefined>Ошибка, если запрос не удался.
statusRef<'idle' | 'pending' | 'success' | 'error'>Статус запроса (см. ниже).
pendingRef<boolean>true, пока запрос выполняется.
clear() => voidСброс data в undefined (или options.default()), error в undefined, status в idle, отмена ожидающих запросов.

Значения status

  • idle: запрос ещё не начался (например, { immediate: false } или { server: false } при SSR)
  • pending: запрос выполняется
  • success: успех
  • error: ошибка
Если на сервере данные не запрашивались (например, server: false), они не загрузятся до завершения гидратации. Даже при await useFetch на клиенте в <script setup>data может оставаться null.

Примеры

Прочитайте и отредактируйте живой пример в Docs > 3 X > Examples > Advanced > Use Custom Fetch Composable.
Прочитайте и отредактируйте живой пример в Docs > 3 X > Examples > Features > Data Fetching.