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

Работа с JSON-данными в Nuxt

Автор

Олег Марков

Введение

JSON стал стандартом для передачи данных между клиентом и сервером в современных веб-приложениях. Если вы создаете приложение на Nuxt – популярном фреймворке для Vue – чаще всего вам нужно будет получать, преобразовывать и отправлять именно JSON-данные. Знание того, как правильно это делать, позволит ускорить интеграцию сторонних API, загрузку данных из локальных файлов, а также обеспечит удобную работу с реактивностью Nuxt.

В этой статье я подробно расскажу, как взаимодействовать с JSON-данными в Nuxt: от простого получения информации по API до более продвинутых тем вроде валидирования, сериализации, реактивной работы и взаимодействия с хранилищем данных. Мы рассмотрим практические подходы, чтобы вы сразу могли применять полученные знания в своем проекте.

Как получать JSON-данные в Nuxt

Получение данных во время сервера (SSR) или перед рендером страницы

Nuxt позволяет легко загружать данные, когда страница только готовится к рендеру. Для этого отлично подходят асинхронные методы, такие как asyncData и fetch. Вот пример того, как получить JSON с помощью asyncData:

// pages/posts.vue

export default {
  async asyncData({ $axios }) {
    // Здесь мы делаем запрос к внешнему API, например JSONPlaceholder
    const posts = await $axios.$get('https://jsonplaceholder.typicode.com/posts')
    // Вернем объект, который попадет в data компонента
    return { posts }
  }
}

В данном примере Nuxt сам отдаст данные из API до рендера страницы, а ваш компонент получит уже готовый массив объектов. Это удобно для SEO и для ускорения первой загрузки.

Работа с JSON - это основа для взаимодействия с API и обмена данными в Nuxt-приложениях. Чтобы эффективно работать с JSON, необходимо понимать структуру JSON, уметь сериализовать и десериализовать данные и правильно обрабатывать ошибки. Если вы хотите узнать больше о работе с JSON в Nuxt, приходите на наш большой курс Nuxt - fullstack Vue фреймворк. На курсе 129 уроков и 13 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Использование fetch, чтобы загружать данные на клиенте

Кроме asyncData, вы можете использовать хук fetch:

export default {
  data() {
    return { posts: [] }
  },
  async fetch() {
    // Этот код выполняется и на сервере, и на клиенте (при навигации)
    this.posts = await this.$axios.$get('https://jsonplaceholder.typicode.com/posts')
  }
}

Когда используете fetch, результат запроса помещается прямо в реактивное состояние компонента. Такой подход удобен для обновляемых списков, новостей, ленты и т.д.

Загрузка локальных JSON-файлов

Иногда удобнее хранить данные рядом с приложением — например, в статических файлах. Для загрузки локальных файлов JSON используйте стандартный import или глобальный fetch:

// Если файл лежит в папке static/data/data.json
export default {
  async asyncData({ req }) {
    // На сервере можно использовать fs/promises, но проще загружать через HTTP
    const res = await fetch('http://localhost:3000/data/data.json')
    const localData = await res.json()
    return { localData }
  }
}

В Nuxt 3 и выше поддержан import для небольших файлов:

// data.json импортируется как обычный модуль
import localData from '~/static/data/data.json'

export default {
  data() {
    return { localData }
  }
}

Особенности обработки больших JSON-файлов

Когда размер данных велик (например, десятки мегабайт), старайтесь минимизировать объем передаваемого JSON или использовать пагинацию на сервере. Всегда учитывайте, что большие payload замедляют загрузку страницы.

Работа с Axios и JSON в Nuxt

Почему Axios чаще используется в Nuxt

Nuxt уже (во втором поколении) поддерживает модуль axios и настраивает его для удобной работы. Вот пример конфигурации:

// nuxt.config.js
export default {
  modules: [
    '@nuxtjs/axios'
  ],
  axios: {
    baseURL: 'https://jsonplaceholder.typicode.com'
  }
}

Теперь делать запросы можно из любого компонента через $axios:

// Получение одного поста по id
async asyncData({ $axios, params }) {
  const post = await $axios.$get(`/posts/${params.id}`)
  return { post }
}

Свойство $axios.$get автоматически преобразует ответ из JSON в объект.

Настройка заголовков для работы с JSON

Часто при работе с внешними API нужно настроить заголовки для отправки или приема JSON:

// Отправка POST-запроса с телом в формате JSON
await this.$axios.$post('/posts', { title: 'Заголовок', body: 'Текст' }, {
  headers: { 'Content-Type': 'application/json' }
})

Как правило, axios эти заголовки подставляет автоматически, если передаете объект.

Преобразование, парсинг и сериализация JSON

Преобразование строки JSON в объект

Чтобы превратить текст в объект, используется стандартный метод JSON.parse:

const jsonString = '{"name":"Alex","age":26}'
// Вот так получается объект из строки
const user = JSON.parse(jsonString)

Если структура невалидна, сработает исключение — всегда обрабатывайте его:

try {
  const user = JSON.parse(jsonString)
  // здесь user — валидный объект
} catch (e) {
  // обработка ошибки
  console.error('Ошибка парсинга', e.message)
}

Преобразование объекта в строку (сериализация)

Чтобы отправить объект, его нужно сериализовать:

const post = { title: 'Nuxt', description: 'Работа с JSON' }
// превращаем в строку JSON
const jsonPost = JSON.stringify(post)

Этот подход полезен при работе с fetch или при сохранении состояния во внешние системы.

Глубокая копия объекта через JSON

Есть лайфхак — если нужно сделать копию сложного объекта (без вложенных реактивных ссылок), используйте:

const copy = JSON.parse(JSON.stringify(originalObj))
// Обратите внимание: так не копируются функции и спец.типы (Date, Map, Set)

Валидирование и нормализация JSON

Перед тем как обрабатывать данные с API или из сторонних источников, их часто нужно привести к нужному виду (нормализовать) и проверить структуру.

Пример простого валидатора

Покажу вам на примере:

function validatePost(data) {
  // Проверяем, что обязательные поля присутствуют и имеют правильный тип
  return data &&
    typeof data.title === 'string' &&
    typeof data.body === 'string' &&
    typeof data.id === 'number'
}

Для сложных структур можно использовать библиотеки вроде yup или zod:

import * as yup from 'yup'

const postSchema = yup.object().shape({
  id: yup.number().required(),
  title: yup.string().required(),
  body: yup.string().required()
})

async function isValidPost(post) {
  try {
    await postSchema.validate(post)
    return true
  } catch (e) {
    return false
  }
}

Этот подход помогает защитить приложение от некорректных структур.

Отображение JSON-данных во Vue-компонентах Nuxt

Привязка данных к шаблону

В Nuxt, как и во Vue, вы можете напрямую показывать данные из JSON-объекта:

<template>
  <div>
    <h2 v-for="post in posts" :key="post.id">{{ post.title }}</h2>
  </div>
</template>

<script>
export default {
  async asyncData({ $axios }) {
    const posts = await $axios.$get('/posts')
    return { posts }
  }
}
</script>

Форматирование и вывод "сырых" данных

Иногда useful (для отладки или показа структуры) выводить JSON в "сыром" виде:

<pre>{{ JSON.stringify(posts, null, 2) }}</pre>

Это покажет красиво форматированный JSON без искажений.

Реактивные структуры для JSON

Все, что помещается в свойство data или возвращается из asyncData, становится реактивным — т.е. при обновлении данных автоматически обновится и отображение.

Хранение и манипуляция JSON-данными с помощью состояния (store)

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

Если вы хотите разделить логику получения и отображения данных, используйте store:

// store/posts.js
export const state = () => ({
  items: []
})

export const mutations = {
  setPosts(state, posts) {
    state.items = posts
  }
}

export const actions = {
  async fetchPosts({ commit }, $axios) {
    const posts = await $axios.$get('/posts')
    commit('setPosts', posts)
  }
}

Затем в компонентах данные можно получать через mapState или напрямую через this.$store.state.posts.items.

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

В Nuxt 3 рекомендуют использовать Pinia:

// stores/posts.js
import { defineStore } from 'pinia'
export const usePostsStore = defineStore('posts', {
  state: () => ({ items: [] }),
  actions: {
    async fetchPosts() {
      const res = await $fetch('/api/posts')
      this.items = res
    }
  }
})

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

Преобразование и фильтрация JSON-данных

Пример: отображение только опубликованных статей

const publishedPosts = posts.filter(post => post.published === true)

Или, если нужно отсортировать:

const sorted = posts.sort((a, b) => b.date.localeCompare(a.date))

Производите такие преобразования в вычисляемых свойствах (computed) или непосредственно перед выводом в шаблон.

Работа с пользовательским API и Nuxt server/api (Nuxt 3)

Nuxt 3 ввел server routes и API, которые упрощают генерацию собственных JSON-ответов внутри приложения:

// server/api/posts.js
export default () => [
  { id: 1, title: 'Пример', body: 'Текст' }
]

Теперь вы можете обращаться к этому API внутри приложения, используя /api/posts.

const posts = await $fetch('/api/posts')

Вы также можете возвращать любые собственные структуры JSON.

Работа с JSON - это важная часть разработки современных веб-приложений. Чтобы создавать гибкие и масштабируемые приложения, необходимо освоить все возможности фреймворка, включая работу с сервером, базами данных и API. На нашем курсе Nuxt - fullstack Vue фреймворк вы найдете все необходимые знания и навыки для достижения успеха. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в Nuxt прямо сегодня.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Как отправить JSON-данные на сервер в Nuxt 3 через $fetch?

Используйте функцию $fetch, она сама сериализует объект:

const response = await $fetch('/api/posts', {
  method: 'POST',
  body: { title: 'Заголовок', content: 'Текст' }
})
// Преобразование происходит автоматически; Content-Type application/json выставляется по умолчанию

Почему не работает import JSON-файла в Nuxt 2?

В Nuxt 2 import JSON допустим только внутри папки assets или static для небольших файлов. Для больших файлов или если импортировать напрямую не выходит, загружайте их через HTTP (fetch('/data/file.json')).

Как валидировать полученные по API JSON-данные в runtime?

Лучше всего использовать библиотеки yup, zod, joi (см. пример выше). Можете написать свой валидатор, который будет проверять структуру объектов до передачи в хранилище или компонент.

Как защититься от XSS при выводе JSON в шаблоне?

Выводите сырые JSON-данные только внутри <pre>{{ JSON.stringify(data) }}</pre>. Никогда не используйте v-html для вставки данных, полученных из внешнего API.

Как динамически реагировать на обновление JSON после асинхронной загрузки?

Ваша структура данных должна быть реактивной (например, хранится в data, state, Pinia store). После получения новых данных просто присваивайте их переменной (this.list = newData), и компоненты обновят отображение автоматически.

Стрелочка влевоКоманды для запуска NuxtКак настроить HTML-шаблон в NuxtСтрелочка вправо

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

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

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

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

Все гайды по Nuxt

Генерация статического сайта с помощью NuxtКак использовать useAsyncData в NuxtКак использовать SVG в NuxtКоманды для запуска NuxtРабота с JSON-данными в NuxtКак настроить HTML-шаблон в NuxtРуководство по получению данных с Fetch в NuxtГенерация статического сайта с помощью NuxtКак отключить определенные функции в NuxtРабота с данными в Nuxt с помощью useNuxtDataНастройка и использование cookie в NuxtГайд по аутентификации (auth) в NuxtКак создавать API-маршруты в Nuxt
Использование Vite для ускорения разработки в NuxtРуководство по использованию TypeScript в NuxtКак запустить Nuxt-приложение в productionКак работает Server-Side Rendering SSR в NuxtНастройка и оптимизация серверной части 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 ₽
Подробнее

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