Олег Марков
Работа с данными в Nuxt с помощью useNuxtData
Введение
Когда вы работаете над современным веб-приложением, задача получения и управления асинхронными данными часто выходит на первый план. В Nuxt, начиная с третьей версии, появился удобный инструмент для этой задачи — composable-функция useNuxtData
. Она создана для того, чтобы сделать работу с данными унифицированной, эффективной и простой как на сервере, так и на клиенте, с поддержкой кеширования и реактивности "из коробки". В этой статье я подробно расскажу вам, как использовать useNuxtData
: от базовой загрузки данных до продвинутых техник управления актуальностью, SSR, стратегиями кеширования и повторного получения данных.
Что такое useNuxtData
useNuxtData
— это composable-функция из Nuxt 3, которая позволяет вам управлять асинхронными данными, кэшировать результат, безопасно работать с ними при Server Side Rendering и легко использовать полученную информацию в компонентах.
Почему это важно? Реактивное получение данных и автоматический SSR-контекст — основа создания быстрых, SEO-оптимизированных приложений. Передача данных с сервера на клиент становится прозрачной, экономя вам время и ресурсы.
Эффективное получение и передача данных - это основа для создания динамичных и интерактивных Nuxt-приложений. Но для оптимизации этого процесса необходимо понимать, как работают различные методы получения данных, как кэшировать запросы и как обрабатывать большие объемы данных. Если вы хотите узнать больше о способах получения и передачи данных в Nuxt, приходите на наш большой курс Nuxt - fullstack Vue фреймворк. На курсе 129 уроков и 13 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.
Главное отличие от useAsyncData и useFetch
Если вы работали с функциями useAsyncData
или useFetch
, то, скорее всего, сталкивались с необходимостью ручного управления идентификаторами, кешированием и передачей данных. С появлением useNuxtData
эти задачи переключились на более удобный уровень, ведь теперь механизм хранения и повторного использования данных реализован "под капотом".
Основные возможности и синтаксис useNuxtData
Давайте начнем с того, как выглядит базовое использование этого composable.
// Пример работы с useNuxtData для загрузки списка пользователей
const { data, pending, error, refresh } = await useNuxtData('users', async () => {
// Здесь происходит асинхронный запрос на сервер
const { users } = await $fetch('/api/users')
return users
})
'users'
— уникальный ключ для кэширования и идентификации данных- Второй аргумент — асинхронная функция, которая возвращает ваши данные
Теперь разберем, что конкретно нам дает результат вызова:
- data — реактивное состояние данных. Привязывайте прямо к UI.
- pending — индикатор загрузки (true, пока работает асинхронная функция)
- error — содержит ошибку, если она возникла
- refresh — функция для повторной загрузки данных
Эти свойства реактивны и автоматически обновятся, если вы снова вызовете загрузчик (refresh()
).
Когда и как использовать useNuxtData
Смотрите, в отличие от других способов загрузки данных, useNuxtData
оптимален, когда:
- Нужно разделить данные между компонентами без повторных запросов
- Важно распределять логику работы с данными на сервере и клиенте
- Есть необходимость кастомизировать стратегии кеширования
Особенности работы с useNuxtData
Кэширование и уникальность ключа
Nuxt кэширует результат по вашему ключу — 'users'
из примера выше. Это значит, что при повторном вызове с тем же ключом запрос не повторится, а результат будет возвращён мгновенно.
Обратите внимание: если ключ одинаковый для разных функций — результат будет браться из первого выполненного запроса.
// В обоих случаях результат будет общий, если ключ 'profile' один и тот же
useNuxtData('profile', ... )
useNuxtData('profile', ... )
Чтобы избежать коллизий — добавляйте к ключу динамические параметры, например ID пользователя:
const userId = 42
useNuxtData(`user-${userId}`, async () => { ... })
SSR, SSG и Client hydration
Когда используется SSR или SSG, Nuxt гарантирует, что результат выполнения асинхронной функции будет встроен в HTML и "реиспользован" на клиенте. Это решает типичные проблемы с двойными запросами, когда после рендера сервером данные еще раз пытаются подгрузиться на клиенте.
Давайте посмотрим, как выглядит передача данных:
- На сервере все асинхронные функции из useNuxtData выполняются до рендера страницы.
- Полученные данные сериализуются и передаются на клиент.
- На клиенте повторный вызов useNuxtData с тем же ключом заполняет data немедленно, без запроса к серверу.
Реактивность
Свойства, получаемые из useNuxtData, полностью реактивны. Например, если вы вызовете refresh, компонент тут же отреагирует на новые данные. Это позволяет строить живые интерфейсы без дополнительного кода.
Пример в компоненте
Давайте реализуем полноценный пример компонента:
<script setup>
const { data: posts, pending, error, refresh } = await useNuxtData('posts', async () => {
// Имитация загрузки списка постов
return await $fetch('/api/posts')
})
</script>
<template>
<div>
<button @click="refresh" :disabled="pending">Обновить список постов</button>
<div v-if="pending">Загрузка...</div>
<div v-else-if="error">Ошибка: {{ error.message }}</div>
<ul v-else>
<li v-for="post in posts" :key="post.id">{{ post.title }}</li>
</ul>
</div>
</template>
// Здесь компонент сразу отображает данные, реагирует на загрузку и ошибку, позволяет вручную обновить содержимое
Интеграция с серверными и клиентскими плагинами
useNuxtData
можно использовать для загрузки данных не только из API, но и из ваших серверных функций (server/api/XXX.ts
) или кастомных composable-функций. Это даёт гибкость при структурировании приложения.
Пример загрузки через серверную функцию
const { data, pending, error } = await useNuxtData('user-stats', async () => {
// Запрашиваем данные из server/api/userStats.ts
return await $fetch('/api/userStats')
})
Пример использования с composable
// Создаем composable-функцию useCurrentUser.js
export function useCurrentUser() {
return useNuxtData('current-user', async () => await $fetch('/api/current-user'))
}
// Использование в компоненте
const { data: currentUser } = await useCurrentUser()
Переиспользование и шаринг данных между компонентами
Благодаря кешированию по ключу, вы можете вызывать useNuxtData в разных частях вашего приложения с одним и тем же ключом, и получать одни и те же данные, синхронизированные между всеми компонентами.
Управление ошибками и состояние загрузки
useNuxtData
возвращает реактивные переменные ошибки и статуса загрузки, которые можно использовать прямо в шаблоне или логике компонента.
if (pending.value) {
// Показываем индикатор загрузки
}
if (error.value) {
// Логируем или отображаем error.message
}
Правильное использование await с useNuxtData
В большинстве случаев вы можете использовать await с useNuxtData в даже в клиентских компонентах. Nuxt сам управляет сериализацией данных между сервером и клиентом, при необходимости ожидает завершения промисов на сервере до рендера.
Расширенные возможности useNuxtData
Сброс кеша и ручное обновление
Если нужно обновить или сбросить кеш, используйте функцию refresh, возвращаемую useNuxtData. Это актуально, если, например, данные могли измениться на сервере.
refresh() // Выполняет повторную загрузку
Можно использовать этот механизм для реализации Pull-To-Refresh или реакций на действия пользователя.
Использование с Nuxt Plugins и Middleware
useNuxtData применяется внутри плагинов для сложных сценариев — например, загрузки настроек приложения, информации о сессии или даже кастомных стратегий предзагрузки данных через middleware.
SSR – предварительная загрузка больших объемов данных
С помощью useNuxtData легко оптимизировать SSR, чтобы сразу отдавать пользователю готовые данные в initial HTML. Просто вызывайте useNuxtData с нужными ключами и асинхронными функциями в setup-компонентов или в middleware на сервере.
Работа с реактивными параметрами (key-функция)
Вы можете создавать ключ на основе реактивных переменных, чтобы управлять корректным кешированием разных данных:
const userId = ref(10)
const { data } = await useNuxtData(
() => `user-${userId.value}`,
async () => await $fetch(`/api/user/${userId.value}`)
)
// Если userId.value изменится, useNuxtData автоматически обновит данные под новым ключом
Совместное использование с useFetch и useAsyncData
В некоторых случаях удобно совместно использовать эти composable-функции, чтобы гибко управлять жизненным циклом данных, делать загрузку данных условно (например — сперва useNuxtData, если кеш есть, затем useFetch для специфических запросов).
Практические советы и лучшие практики
- Используйте префиксы в ключах — это позволяет четко разграничивать области данных и избегать конфликтов при именовании, например "user-profile-42" вместо "profile".
- Ограничивайте объем данных, которые кэшируете — не храните слишком большие структуры, чтобы не нагружать память.
- Удаляйте устаревшие ключи вручную, если работаете со сложным состоянием — используйте refresh для обновления информации.
- Добавляйте проверку ошибок — используйте возвращаемое поле error для явного отображения проблем с сетью или бэкендом.
- Не дублируйте вызовы с одинаковым ключом для разных данных — следите за тем, чтобы ключ уникально отражал суть получаемых данных.
Заключение
useNuxtData — это современный и мощный инструмент для управления асинхронными данными в Nuxt-приложениях. Он позволяет унифицировать работу с загрузкой данных, удобно кэшировать, использовать реактивные состояния и интегрироваться как с серверными, так и клиентскими частями приложения. Благодаря гибкому API и поддержке SSR/SSG вы можете быстро создавать производительные и динамичные приложения, не заморачиваясь с ручным кешированием или многократными запросами.
Работа с данными - это один из ключевых аспектов веб-разработки. Чтобы создавать гибкие и масштабируемые приложения, необходимо освоить все возможности фреймворка, включая работу с сервером, базами данных и API. На нашем курсе Nuxt - fullstack Vue фреймворк вы найдете все необходимые знания и навыки для достижения успеха. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в Nuxt прямо сегодня.
Частозадаваемые технические вопросы по теме статьи и ответы на них
Как сбросить кэш useNuxtData для определенного ключа вручную?
Для этого вызовите функцию refresh, возвращаемую useNuxtData с нужным ключом. Если нужно сбросить все данные с этим ключом, просто вызовите refresh(), например:
js
const { refresh } = await useNuxtData('posts', ...)
refresh() // данные будут загружены заново
Можно ли использовать useNuxtData в layout или middleware?
Да, useNuxtData можно вызывать внутри layout-компонентов и даже middleware. В middleware вызовите функцию и дождитесь её завершения через await — данные будут загружены до рендера страницы.
Что делать, если данные зависят от параметров маршрута?
Сгенерируйте ключ на основе параметров, например:
js
const route = useRoute()
const { data } = await useNuxtData(
() => `user-${route.params.id}`,
async () => await $fetch(`/api/user/${route.params.id}`)
)
Это гарантирует уникальность кеша для разных параметров.
Как обработать multiple pending состояний для разных useNuxtData?
Храните состояние pending отдельно для каждого вызова useNuxtData — каждая функция возвращает своё pending, error и data, которые независимы друг от друга.
Как отменить запрос useNuxtData, если компонент демонтируется?
useNuxtData не предоставляет явного механизма abort. Однако, если компонент размонтируется до завершения загрузки, Nuxt автоматически "сбрасывает" состояние — повторных сайд-эффектов не будет. Если нужна ручная отмена, реализуйте её через сторонние библиотеки или контролируйте это в функции-загрузчике через AbortController.
Постройте личный план изучения Nuxt до уровня Middle — бесплатно!
Nuxt — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Nuxt
Лучшие курсы по теме

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