логотип PurpleSchool
логотип PurpleSchool

Работа с данными в 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 для специфических запросов).

Практические советы и лучшие практики

  1. Используйте префиксы в ключах — это позволяет четко разграничивать области данных и избегать конфликтов при именовании, например "user-profile-42" вместо "profile".
  2. Ограничивайте объем данных, которые кэшируете — не храните слишком большие структуры, чтобы не нагружать память.
  3. Удаляйте устаревшие ключи вручную, если работаете со сложным состоянием — используйте refresh для обновления информации.
  4. Добавляйте проверку ошибок — используйте возвращаемое поле error для явного отображения проблем с сетью или бэкендом.
  5. Не дублируйте вызовы с одинаковым ключом для разных данных — следите за тем, чтобы ключ уникально отражал суть получаемых данных.

Заключение

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Настройка и использование cookie в NuxtСтрелочка вправо

Постройте личный план изучения Nuxt до уровня Middle — бесплатно!

Nuxt — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Nuxt

Генерация статического сайта с помощью NuxtКак использовать useAsyncData в NuxtКак использовать SVG в NuxtКоманды для запуска NuxtРабота с JSON-данными в NuxtКак настроить HTML-шаблон в NuxtГенерация статического сайта с помощью NuxtРуководство по получению данных с Fetch в NuxtКак отключить определенные функции в NuxtРабота с данными в Nuxt с помощью useNuxtDataНастройка и использование cookie в NuxtГайд по аутентификации (auth) в NuxtКак создавать API-маршруты в Nuxt
Использование Vite для ускорения разработки в NuxtРуководство по использованию TypeScript в NuxtКак работает Server-Side Rendering SSR в NuxtКак запустить Nuxt-приложение в productionНастройка и оптимизация серверной части Nuxt-приложенияРуководство по настройке маршрутизации в NuxtКакие проекты разумно реализовывать на NuxtИнструкция по управлению пакетами NPM в NuxtИнтеграция Node.js для Nuxt-приложенияНастройка мета-тегов для SEO в NuxtНастройка и использование HTTPS в NuxtКак отлавливать и обрабатывать ошибки в NuxtКак развернуть Nuxt приложение в DockerРуководство по развертыванию приложений в Nuxt CloudКак оптимизировать сборку на NuxtИнтеграция Laravel и Nuxt
Открыть базу знаний

Лучшие курсы по теме

Иконка ракетыСкоро!
изображение курса

Nuxt

Антон Ларичев
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий