Олег Марков
Руководство по получению данных с Fetch в Nuxt
Введение
В современном веб-разработке одним из распространённых фреймворков для создания приложений на Vue является Nuxt. Получение и обработка внешних данных — ключевая задача при построении динамических веб-продуктов. Nuxt предлагает эффективные инструменты для реализации этой задачи, в частности, функцию fetch
, которая упрощает процесс загрузки данных на серверной и клиентской стороне, автоматически учитывает асинхронность и делает код чище.
В этой статье я подробно расскажу вам, как использовать механизм fetch в Nuxt как в классическом Nuxt 2
, так и в актуальном Nuxt 3
, разберём ключевые различия, особенности разных подходов, организацию запросов, обработку ошибок и оптимизацию под реальные задачи. Я приложу понятные примеры, чтобы упростить вам интеграцию fetch в свой проект, и расскажу о типичных проблемах, с которыми обычно сталкиваются разработчики.
Различия между Nuxt 2 и Nuxt 3 в получении данных
Fetch в Nuxt 2
В Nuxt 2
существует встроенный хук fetch
, который позволяет получать данные серверным или клиентским методом в зависимости от режима рендеринга. Важно понимать, что fetch
в Nuxt 2 не то же самое, что стандартная функция браузерного API fetch. Это отдельная концепция, которая оптимизирована под SSR и SPA режимы Nuxt.
Пример использования fetch в Nuxt 2
export default {
data() {
return {
post: null
}
},
async fetch() {
// Получаем данные о посте с удалённого API
this.post = await this.$axios.$get('https://jsonplaceholder.typicode.com/posts/1')
}
}
Здесь важный момент: внутри хуков жизненного цикла (типа fetch
) не нужно явно возвращать данные. Данные просто присваиваются свойствам компонента.
Основные особенности fetch в Nuxt 2
fetch
вызывается как на сервере (при SSR), так и на клиенте (при SPA-навигации).- Поддерживает автоматическую повторную загрузку данных при изменении параметров маршрута через опцию
watchQuery
. - Иногда в Nuxt 2 используется вместе с
asyncData
(еще один мощный хук для получения данных, но с другим поведением).
Fetch в Nuxt 3
В Nuxt 3
упор смещается на поддержку Composition API и использование нового синтаксиса. Здесь отсутствует отдельный хук fetch у компонента, а для асинхронной загрузки данных вводится специальная функция useFetch
.
Получение данных с использованием Fetch является одним из основных способов взаимодействия с API в Nuxt-приложениях. Чтобы делать это эффективно и безопасно, необходимо понимать, как работает Fetch API, как обрабатывать ошибки и как кэшировать данные. Если вы хотите узнать больше о получении данных с помощью Fetch в Nuxt, приходите на наш большой курс Nuxt - fullstack Vue фреймворк. На курсе 129 уроков и 13 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.
Пример использования useFetch в Nuxt 3
<script setup>
// Импортируем функцию useFetch от Nuxt
const { data: post, error, pending } = await useFetch('https://jsonplaceholder.typicode.com/posts/1')
</script>
В этом примере мы видим декларативную загрузку данных с автоматической обработкой статусов загрузки (pending
) и ошибок (error
).
Основные особенности useFetch в Nuxt 3
- Интеграция с Composition API (используйте внутри
<script setup>
, поскольку это хук). - Автоматическая поддержка SSR — данные подгружаются на сервере, а затем гидратируются на клиенте.
- Позволяет типизировать данные (через TS-дженерики), кэшировать запросы, управлять повторными вызовами.
Как работает серверный рендеринг (SSR) с Fetch
Одна из главных сильных сторон Nuxt — возможность SSR. Правильное использование fetch позволяет наполнять страницы сразу данными при генерации, сокращая время до появления содержимого для пользователя.
SSR-поток в Nuxt 2
- При первом запросе к странице с SSR Nuxt вызывает ваш fetch-хук.
- Фреймворк ждёт завершения всех асинхронных fetch-операций прежде чем построить HTML.
- То есть к моменту отправки ответа клиенту страница уже наполнена требуемыми данными.
- Дальнейшие SPA-навигации используют fetch только на клиенте.
SSR-поток в Nuxt 3
- Аналогично —
useFetch
вызывается внутри установки компонента, Nuxt ждет выполнения Promise до генерации HTML. - Если вы кэшируете данные, они могут быть автоматически повторно использованы при SPA переходах.
- Возможен запуск в нативном серверном окружении (например, Edge Functions).
Получение данных с помощью fetch в разных сценариях
Получение данных на стороне сервера
Вам часто нужно получить данные, которые должны быть доступны сразу при загрузке страницы — например, контент для SEO, важные для рендеринга элементы.
Nuxt 2
export default {
async fetch() {
this.product = await this.$axios.$get('/api/product/123')
// Здесь product попадёт сразу в отрендеренный HTML
}
}
Nuxt 3
<script setup>
const { data: product } = await useFetch('/api/product/123')
/* product будет получен на сервере и попадёт в финальный HTML */
</script>
Обратите внимание, что в обоих случаях Nuxt сам управляет моментом, когда будет происходить рендеринг, подождав все асинхронные действия.
Получение данных только на клиенте
Бывают ситуации, когда данные нужны только после загрузки (например, чувствительные к окружению данные или когда API недоступно с бэкенда).
Nuxt 2
export default {
mounted() {
// Этот код выполнится только на клиенте
this.fetchFromBrowser()
},
methods: {
async fetchFromBrowser() {
this.userAgentData = await fetch('/api/userinfo').then(res => res.json())
}
}
}
Nuxt 3
<script setup>
import { onMounted } from 'vue'
const userAgentData = ref(null)
onMounted(async () => {
// Данные будут получены только на клиенте
userAgentData.value = await $fetch('/api/userinfo')
})
</script>
Использование собственного сервера API (Nuxt API routes)
Nuxt 3 позволяет создавать внутренние серверные API, которые удобно использовать для получения данных в приложении.
Пример handler из server/api/posts.ts
// Это файл серверного обработчика Nuxt 3
export default defineEventHandler(async (event) => {
const posts = await fetch('https://my.external.api/posts').then(r => r.json())
return posts
})
Получение данных с API-роута из компонента
<script setup>
const { data: posts } = await useFetch('/api/posts')
</script>
Этот подход повышает безопасность (API-ключи не светятся на клиенте) и позволяет кэшировать логику.
Обработка ошибок и статусов загрузки
В современных приложениях важно предоставить пользователю корректные статусы: идёт загрузка, произошла ошибка, данные успешно загружены.
Nuxt 3: обработка ошибок и загрузки
<script setup>
const { data, error, pending } = await useFetch('/api/posts')
if (pending.value) {
// Покажите индикатор загрузки
}
if (error.value) {
// Покажите ошибку
}
if (data.value) {
// Выводите данные
}
</script>
Nuxt 2: обработка загрузки и ошибок
В Nuxt 2 можно использовать дополнительные флаги в data или computed:
export default {
data() {
return {
post: null,
loading: false,
error: null
}
},
async fetch() {
this.loading = true
try {
this.post = await this.$axios.$get('/api/post')
} catch (e) {
this.error = e
} finally {
this.loading = false
}
}
}
Обратите внимание, что для отображения состояний достаточно реактивных свойств.
SSR или SPA: Когда использовать fetch, а когда asyncData или useAsyncData
В Nuxt 2 есть два похожих механизма: fetch
и asyncData
. В Nuxt 3 — основное отличие между useFetch
и useAsyncData
заключается в кэшировании и повторном использовании.
asyncData (Nuxt 2)
- asyncData вызывается ПЕРЕД созданием экземпляра компонента.
- Не имеет доступа к
this
, вы напрямую возвращаете объект с данными. - Чаще используйте
asyncData
в страницах там, где нужны данные до рендера компонента.
export default {
async asyncData({ $axios, params }) {
const post = await $axios.$get(`/api/posts/${params.id}`)
return { post }
}
}
useAsyncData (Nuxt 3)
Похож на useFetch, но обычно используется там, где необходима большая гибкость (например, разные источники данных, трансформации).
<script setup>
const { data, pending, error } = await useAsyncData('unique-key', () =>
$fetch('/api/posts')
)
</script>
- Преимущество: ручное управление кэшированием через ключи.
- Позволяет самому определять когда и как загружать данные.
Организация и типизация запросов
Использование $fetch
$fetch в Nuxt (3) — более высокоуровневый аналог browser fetch с автоматическим парсингом JSON, поддержкой query-параметров, интеграцией с SSR, возможностью передавать заголовки, телом и т. д.
// Получение и отправка данных с $fetch
const data = await $fetch('/api/items', {
method: 'POST',
body: { name: 'item1' }
})
Типизация запросов (TypeScript)
В Nuxt 3 можно сразу добавить дженерики для получения строгой типизации данных.
interface Post {
id: number
title: string
body: string
}
const { data } = await useFetch<Post[]>('/api/posts')
Это помогает избежать ошибок и ускоряет разработку.
Продвинутое использование fetch
Кэширование запросов
В Nuxt 3 можно управлять кэшированием useFetch:
const { data } = await useFetch('/api/items', {
key: 'items-list', // уникальный ключ для кэширования
lazy: true, // не выполнять при монтировании компонента
server: false // всегда выполнять на клиенте
})
key
нужен, если хотите явно управлять кэшированием (например, при пагинации).lazy
— если нужно отложить запрос.server: false
— отключает SSR для конкретного запроса.
Повторные запросы (рефреш)
Иногда нужно вручную обновить данные (например, после отправки формы).
const { data, refresh } = await useFetch('/api/profile')
// ...
await refresh()
Передача параметров в запросе
const { data } = await useFetch('/api/search', {
query: { q: 'nuxt', page: 2 }
})
Безопасность при работе с fetch
Полезнее всего выносить чувствительные операции на серверную часть приложения (в Nuxt 3 внутри папки /server/api
). Это позволит скрыть от клиента API-ключи и другие секреты.
Для чувствительных данных не используйте прямые fetch-запросы из браузера (например, когда требуются приватные ключи).
Если нужно проверять авторизацию, вы можете воспользоваться middlewares или обрабатывать куки токены в серверных API-роутах.
Заключение
Механизм fetch в Nuxt — это мощный инструмент для получения, кэширования и обработки данных как на сервере, так и на клиенте. В Nuxt 2 и Nuxt 3 подходы немного отличаются, однако оба варианта предполагают удобыню интеграцию с жизненным циклом страниц, поддержку SSR и SPA, работу с ошибками и состояниями загрузки, а также продвинутые способы кэширования и рефреша данных.
Получение данных с помощью Fetch — это важный навык для любого веб-разработчика. Чтобы создавать гибкие и масштабируемые приложения, необходимо освоить все возможности фреймворка, включая работу с сервером, базами данных и API. На нашем курсе Nuxt - fullstack Vue фреймворк вы найдете все необходимые знания и навыки для достижения успеха. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в Nuxt прямо сегодня.
Частозадаваемые технические вопросы по теме статьи и ответы на них
Как использовать fetch в Nuxt 3 для динамических маршрутов с параметрами?
Внутри файла страницы используйте функцию useRoute или считывайте параметры прямо из маршрута:
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
const { data } = await useFetch(`/api/posts/${route.params.id}`)
</script>
Таким образом данные будут обновляться при изменении параметра маршрута.
Можно ли использовать fetch или useFetch при статической генерации Nuxt (SSG)?
Да, Nuxt автоматически вызывает useFetch или asyncData при генерации каждой страницы. Убедитесь, что ваши запросы не требуют данных рантайма (например, cookies, headers пользователя), так как они не будут доступны при генерации на этапе build.
Как обработать токены авторизации в fetch-запросах Nuxt 3?
Используйте $fetch с передачей заголовков или проксируйте запрос через серверные API-роуты:
const { data } = await useFetch('/api/private', {
headers: { Authorization: `Bearer ${myToken}` }
})
Или создайте обработчик на сервере, который сам добавит токен.
Что делать, если useFetch не обновляет данные после навигации?
Добавьте уникальный ключ для useFetch или явно используйте метод refresh при необходимости обновления данных:
const { data, refresh } = await useFetch('/api/posts', { key: route.fullPath })
Как отменить или прервать запрос useFetch, если компонент размонтируется до получения ответа?
В текущей реализации Nuxt 3 useFetch не поддерживает автоматическую отмену на уровне API, однако вы можете использовать стандартный AbortController:
const controller = new AbortController()
const { data } = await useFetch('/api/heavy', { signal: controller.signal })
// ...
onUnmounted(() => controller.abort())
Этот подход помогает избежать утечек памяти при длительных или часто отменяемых запросах.
Постройте личный план изучения Nuxt до уровня Middle — бесплатно!
Nuxt — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Nuxt
Лучшие курсы по теме

Nuxt
Антон Ларичев
TypeScript с нуля
Антон Ларичев