Олег Марков
Работа с 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 до уровня Middle — бесплатно!
Nuxt — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Nuxt
Лучшие курсы по теме

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