В Nuxt есть несколько встроенных инструментов для механизма получения данных. Это может ввести в заблуждение тех, кто только начинает знакомиться с этим фреймворком.

Чаще всего, вы будете иметь дело с функциями:

  • useFetch
  • $fetch

Но, также может встречаться

  • useAsyncData

Что же это за набор инструментов? Давайте будем разбираться.

Функции $fetch, useFetch и useAsyncData

Эти функции также называют в документации составными или композиционными. Дело в том, что они берут стандартный функционал fetch для выполнения запросов в Javascript и Nuxt накладывает на них дополнительный функционал.

Зачем нужно было создавать эти дополнительные функции?

Дело в том, что код, который обрабатывает Nuxt может выполняться как на клиентской, так и на серверной стороне. Подробнее об этом я рассказывал в базовом курсе по Nuxt:

https://webkyrs.info/category/osnovy-nuxt

и в курсе по работе с Server API Nuxt

https://webkyrs.info/category/rabota-s-server-api-v-nuxt

Нужны были функции, которые бы учитывали особенности выполнения кода (рендеринга Vue компонентов) в обоих этих средах. Стандартная функция fetch для этих целей не подходила. Если использовать ее, получение данных может происходить 2 раза: на сервере и клиенте. 

Нужны были функции, которые бы учитывали эти особенности получения данных для режима Server Side Rendering. Именно поэтому в Nuxt и появились эти дополнительные функции для получения данных.

Функция $fetch

Это основной инструмент для выполнения сетевых запросов в Nuxt. По сути, это обертка (compose) над стандартной javascript функцией fetch (без знака доллара).

$fetch - это алиас (знак доллара) библиотеки ofetch

https://github.com/unjs/ofetch

и это глобально импортировано в Nuxt проект, чтобы мы могли пользоваться этим в любом месте.

Мы можем использовать $fetch напрямую в компонентах

<script setup lang="ts">
async function addProduct() {
  const product = await $fetch('/api/products', {
    method: 'POST',
    body: {
      name: 'Product Name',
      price: 100,
      description: 'Product Description',
      category: 'Category Name'
    }
  })
}
</script>

Также это может использоваться в server api файлах

// server/api/products.ts
export default defineEventHandler(async (event) => {
  const body = await readBody(event);


  // Пример отправки данных на внешний API с помощью $fetch
  const response = await $fetch('https://external-api.com/products', {
    method: 'POST',
    body: {
      name: body.name,
      price: body.price,
      description: body.description,
      category: body.category
    }
  });


  return {
    status: 'success',
    message: 'Product added successfully',
    product: response
  };
});

Функция useFetch

В отличии от $fetch, функцию useFetch мы можем использовать только в компонентах и не можем использовать в Server API.

useFetch не выполняет непосредственно сам запрос, а служит хуком, которая вызовет серверную функцию, которая сделает сам сетевой запрос с помощью функции $fetch. 

<script setup lang="ts">
const { data: product, pending, error } = await useFetch('/api/products', {
  method: 'POST',
  body: {
    name: 'New Product',
    price: 150,
    description: 'A new product description',
    category: 'Category Name'
  }
})
</script>

Этот код вызовет серверный endpoint, где и будет выполнен непосредственный запрос с помощью функции $fetch.

На самом деле, функция useFetch - это "синтаксический сахар" для более простой записи конструкции:

useFetch(url) - эквивалентно useAsyncData(url, () => $fetch(url))

Используя функцию useAsyncData вы можете более гибко настроить механизм выполнения запроса.

Таким образом, мы видим, что useFetch - это обертка над оберткой useAsyncData, которая позволяет перенаправить запрос к $fetch и дождаться результатов выполнения запроса и далее мы уже можем выполнить обработку данных.

Использование функции useAsyncData может выглядеть следующим образом. 

const { data, error } = await useAsyncData('getTodos', () => fetchTodos())

В useAsyncData первый аргумент - это уникальный ключ для кэширования ответа, полученного от второго аргумента, который является функцией запроса. Однако, если вам удобнее, вы можете опустить этот аргумент и передать только функцию запроса. В таком случае уникальный ключ будет сгенерирован автоматически.

Итого

Вы можете посмотреть больше примеров, как эти запросы применяются на практике в моем курсе по Server API Nuxt

https://webkyrs.info/category/rabota-s-server-api-v-nuxt

Чаще всего в компонентах мы используем хук useFetch, который уже на server api будет вызывать алиас $fetch.

Вот такой алгоритм работы.