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

Работа с JSON данными в приложениях Vue

Автор

Олег Марков

Введение

JSON — один из самых популярных форматов обмена данными между клиентом и сервером. Во фронтенд-разработке, особенно при создании SPA на Vue, вы регулярно сталкиваетесь с тем, что нужно получать, парсить, отображать и отправлять такие данные. Работа с JSON лежит в основе интеграции с бекендом, построения динамических интерфейсов, написания форм, списков и многого другого.

В этой статье я расскажу, как обрабатывать JSON в ваших Vue-приложениях. Вы узнаете, как получать и отправлять JSON с помощью fetch и axios, разбирать и сериализовать объекты через методы parse и stringify, эффективно отображать данные в шаблонах и строить реактивные структуры данных. Приведу подробные примеры и поясню, как избежать типичных ошибок.


Работа с JSON: ключевые подходы в Vue

Способы получения JSON-данных во Vue

Vue не предоставляет встроенных средств для получения данных по HTTP, но экосистема позволяет выбрать удобную библиотеку — например, fetch API или axios. Рассмотрим оба варианта.

Получение JSON с помощью fetch

Fetch — современный стандарт работы с HTTP в браузере. Пример запроса:

export default {
  data() {
    return {
      users: [],
      loading: false,
      error: null,
    }
  },
  methods: {
    async fetchUsers() {
      this.loading = true
      this.error = null
      try {
        // Выполняем GET-запрос по url
        const response = await fetch('https://jsonplaceholder.typicode.com/users')
        // Проверяем успешность ответа
        if (!response.ok) throw new Error('Ошибка запроса')
        // Парсим ответ в JSON
        this.users = await response.json()
      } catch (err) {
        this.error = err.message
      } finally {
        this.loading = false
      }
    }
  },
  mounted() {
    // Загружаем данные при инициализации компонента
    this.fetchUsers()
  }
}

Здесь после получения ответа мы используем await response.json() для преобразования потока данных в JavaScript-объект.

Использование axios для работы с JSON

Axios — популярная библиотека, известная простым API и обработкой ошибок. Пример запроса:

import axios from 'axios'

export default {
  data() {
    return {
      posts: [],
      error: null,
    }
  },
  async mounted() {
    try {
      const response = await axios.get('https://jsonplaceholder.typicode.com/posts')
      // Данные автоматически парсятся в JS-объект
      this.posts = response.data
    } catch (err) {
      this.error = err.message
    }
  }
}

Axios сам преобразует JSON-ответы в объекты. Он удобен для работы с REST API и более устойчив к особенностям кросс-доменных запросов.

Парсинг и сериализация JSON

Разбор строк в объекты: JSON.parse

Иногда API возвращает не javascript-объект, а строку в формате JSON. В этом случае используйте JSON.parse, чтобы превратить строку в объект.

const jsonString = '{"id": 1, "name": "Алексей"}'
const user = JSON.parse(jsonString) // user теперь JS-объект

Если структура данных не соответствует ожиданиям, возможны ошибки. Поэтому хорошо использовать try...catch:

try {
  const data = JSON.parse(apiResponse)
} catch (err) {
  // Если API вернул некорректный JSON — обработайте ошибку
  this.error = 'Некорректные данные: ' + err.message
}

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

Когда отправляете данные на сервер (например, с помощью POST), объекты нужно сериализовать:

const newUser = { name: 'Иван', age: 30 }
const requestBody = JSON.stringify(newUser)

Смотрите, теперь объект превращается в строку. Эту строку вы передаёте в теле запроса.

Отправка JSON-данных на сервер

С помощью fetch

POST-запрос с JSON-телом через fetch выглядит так:

async function submitForm() {
  const formData = { name: 'Олег', email: 'oleg@gmail.com' }
  try {
    const response = await fetch('/api/users', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json' // обязательный заголовок!
      },
      body: JSON.stringify(formData)
    })
    // Обработка ответа от сервера
    const result = await response.json()
    console.log(result)
  } catch (error) {
    console.error('Ошибка отправки:', error)
  }
}

Здесь мы сериализуем объект и обязательно передаём заголовок Content-Type.

С помощью axios

Axios упрощает отправку JSON:

async function saveUser(user) {
  try {
    // Второй аргумент axios автоматически сериализует объект
    const response = await axios.post('/api/users', user)
    console.log('Ответ:', response.data)
  } catch (error) {
    console.error('Ошибка:', error)
  }
}

Axios сам выставляет заголовок и сериализует объект.


Использование JSON-данных во Vue-компонентах

Теперь покажу, как удобно работать с вложенными структурами и списками, а также как строить реактивные списки.

Преобразование и выделение нужных данных

Рассмотрим ситуацию, когда сервер присылает вам сложный JSON. Например, список товаров, у которых есть вложенные характеристики:

// Пример ответа API
const response = [
  {
    id: 1,
    name: 'Кофеварка',
    specs: { color: 'черный', volume: 1000 }
  },
  {
    id: 2,
    name: 'Тостер',
    specs: { color: 'белый', slots: 2 }
  }
]

Теперь, чтобы получить список только названий товаров:

const productNames = response.map(item => item.name)
// ['Кофеварка', 'Тостер']

А если надо отобразить их в шаблоне:

<template>
  <div>
    <h2>Список товаров</h2>
    <ul>
      <li v-for="product in products" :key="product.id">
        {{ product.name }} — Цвет: {{ product.specs.color }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      products: []
    }
  },
  async mounted() {
    const resp = await fetch('/api/products')
    this.products = await resp.json()
  }
}
</script>

Обратите внимание: если какое-то свойство может отсутствовать, используйте опциональную цепочку (product.specs?.color) или делайте проверки.

Динамическое изменение и отправка JSON-данных из форм

Рассмотрим, как собрать данные из v-model, обработать их и отправить в формате JSON.

<template>
  <form @submit.prevent="submitData">
    <input v-model="form.name" placeholder="Имя" />
    <input v-model="form.email" placeholder="E-mail" />
    <button type="submit">Отправить</button>
  </form>
</template>

<script>
export default {
  data() {
    return {
      form: {
        name: '',
        email: ''
      }
    }
  },
  methods: {
    async submitData() {
      try {
        const payload = JSON.stringify(this.form)
        // Отправляем POST-запрос
        const response = await fetch('/api/submit', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: payload
        })
        const result = await response.json()
        console.log('Ответ сервера:', result)
      } catch (error) {
        console.error('Ошибка:', error)
      }
    }
  }
}
</script>

Такой подход позволяет преобразовывать любые формы в сериализованные JSON-объекты для отправки.

Рендеринг вложенных JSON-структур

Давайте рассмотрим, как корректно показать вложенные объекты и массивы, если например, у товара есть список тегов или доступных опций:

<template>
  <ul>
    <li v-for="product in products" :key="product.id">
      {{ product.name }}
      <ul>
        <li v-for="tag in product.tags" :key="tag">{{ tag }}</li>
      </ul>
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      products: [
        { id: 1, name: 'Чайник', tags: ['акция', 'кухня'] },
        { id: 2, name: 'Блендер', tags: ['скидка'] }
      ]
    }
  }
}
</script>

Здесь мы проходим по основному списку и выводим дополнительную вложенную информацию. Такой способ раскрытия структуры удобен при отображении сложных данных.

Реактивность при изменениях JSON

Важно понимать, что Vue отслеживает добавление и удаление свойств, но не всегда замечает новые поля, если их не было в начальных данных. Например:

// Это добавит новое свойство, но не всегда будет реактивным
this.someObj.newProp = 'value'

// Правильный способ:
this.$set(this.someObj, 'newProp', 'value') // Vue 2
// или напрямую, если данные определены заранее (Vue 3)

Старайтесь инициализировать все необходимые поля на старте.


Особенности обработки ошибок и работы с невалидным JSON

Работая с API, вы можете столкнуться с поврежденными или неожиданными данными. Лучшие практики:

  • Всегда используйте try...catch при работе с JSON.parse
  • Проверяйте типы и структуру данных перед тем, как их использовать
  • Можно заранее описать типы с помощью TypeScript или валидировать данные вручную:
function isValidUser(obj) {
  return obj && typeof obj.name === 'string' && typeof obj.age === 'number'
}

Универсальный пример комплексной работы с JSON во Vue

Объединим все шаги: сформируем компонент, который загружает, преобразует, отображает и отправляет данные, написанные в форме.

<template>
  <div>
    <h2>Пользователи</h2>
    <ul>
      <li v-for="user in users" :key="user.id">
        {{ user.name }} ({{ user.email }})
      </li>
    </ul>
    <form @submit.prevent="addUser">
      <input v-model="newUser.name" placeholder="Имя" required />
      <input v-model="newUser.email" placeholder="E-mail" required />
      <button type="submit">Добавить пользователя</button>
    </form>
    <div v-if="error" class="error">{{ error }}</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      users: [],
      newUser: { name: '', email: '' },
      error: null
    }
  },
  async mounted() {
    try {
      const resp = await fetch('/api/users')
      this.users = await resp.json()
    } catch (e) {
      this.error = 'Ошибка загрузки пользователей'
    }
  },
  methods: {
    async addUser() {
      try {
        const response = await fetch('/api/users', {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify(this.newUser)
        })
        const created = await response.json()
        this.users.push(created)
        this.newUser = { name: '', email: '' }
      } catch (e) {
        this.error = 'Не удалось добавить пользователя'
      }
    }
  }
}
</script>

Здесь соединены все основные этапы: загрузка данных GET-запросом, сериализация и отправка данных POST-запросом, реактивное обновление списка.


Загрузка статического JSON локально

Иногда данные находятся не на сервере, а прямо в проекта: например, в рамках локального тестирования или настроек.

Вариант 1 (Vue CLI): поместите файл data.json в папку public. js const resp = await fetch('/data.json') const data = await resp.json()

Вариант 2 (импорт через import):

import products from '../data/products.json' // Webpack или Vite поддерживают такое

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

Этот способ подходит для небольших файлов, которые не изменяются на лету.


Особые приемы и лучшие практики

Обработка больших JSON массиво

Если вы работаете с большими данными, разбивайте их на порции, поддерживайте пагинацию, старайтесь не хранить гигантские объекты в памяти.

Сохранение и загрузка JSON в localStorage

Чтобы кэшировать пользовательские данные:

const key = 'user-profile'
// Сохраняем объект в localStorage
localStorage.setItem(key, JSON.stringify(profile))
// Загружаем
const loaded = JSON.parse(localStorage.getItem(key))

Использование сторонних утилит для валидации JSON

Для проверки структуры используйте joi, ajv, yup и другие валидаторы.


Заключение

Работа с JSON-данными является повседневной задачей при создании современных Vue-приложений. Вы научились получать и парсить ответы API, сериализовать объекты, отправлять данные через HTTP-запросы и отображать их во Vue-компонентах. Примеры кода иллюстрируют основные подходы к взаимодействию с вложенными и сложными структурами JSON, а также показывают, как обеспечить реактивность и защититься от ошибок.

Если применять эти принципы, интеграция с внешними сервисами, создание динамических списков и форм станет значительно проще и надежнее.


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

Как обработать массив внутри JSON, если у некоторых элементов отсутствуют нужные поля?

Используйте опциональную цепочку или проверки наличия:
js items.forEach(item => { const name = item?.name || 'Неизвестно' }) Это исключит ошибку доступа к несуществующим данным.

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

В Vue 3 просто изменяйте нужный индекс: js this.users[index] = { ...this.users[index], name: 'Новое имя' } В Vue 2 лучше использовать Vue.set: js this.$set(this.users, index, обновленныйОбъект)

Почему после изменения вложенного массива не обновляется шаблон?

Vue отслеживает только те поля, что были объявлены заранее. Если вы добавили новое поле или вложенный массив после инициализации, убедитесь что структура данных объявлена в data или используйте $set для добавления.

Как получить только определенные поля из большого JSON-объекта?

Сделайте трансформацию с помощью map: js const usersShort = users.map(({ name, email }) => ({ name, email })) Это создаст новый массив с только нужными полями.

Как отправить массив или объект с вложенными структурами на сервер?

Сериализуйте через JSON.stringify: js const complexData = [{ a: 1 }, { b: 2 }] fetch('/api/data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(complexData) }) Сервер примет JSON в виде строки и сможет декодировать структуру.

Стрелочка влевоИспользование библиотек Vue для расширения функционалаКак работать с экземплярами компонента Instance во VueСтрелочка вправо

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

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

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

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

Все гайды по Vue

Руководство по валидации форм во Vue.jsИнтеграция Tiptap для создания редакторов на VueРабота с таблицами во Vue через TanStackИнструкция по установке и компонентам Vue sliderУправление пакетами Vue js с помощью npmУправление пакетами и node modules в Vue проектахКак использовать meta для улучшения SEO на VueПолный гайд по компоненту messages во Vuejs5 правил использования Inertia с Vue и LaravelРабота с модулями и пакетами в VueИнструкция по работе с grid на VueGithub для Vue проектов - подробная инструкция по хранению и совместной работеНастройка ESLint для Vue проектов и поддержка качества кодаОбработка ошибок и отладка в Vue.jsИспользование Vue Devtools для отладки и мониторинга приложенийРабота с конфигурационными файлами и скриптами VueСоздание и настройка проектов Vue с помощью Vue CLI3 способа интеграции Chart.js с Vue для создания графиковРабота с Canvas во VueИнструкция по реализации календаря во VueРабота с Ant Design Vue для создания UI на Vue
Обзор и использование утилит Vue для удобной разработкиРабота с обновлениями компонента и жизненным циклом updateРазрешение конфликтов и ошибок с помощью Vue resolveИспользование query-параметров и их обработка в маршрутах VueЗагрузка и управление состоянием загрузки в VueИспользование библиотек Vue для расширения функционалаРабота с JSON данными в приложениях VueКак работать с экземплярами компонента Instance во VueПолучение данных и API-запросы во Vue.jsЭкспорт и импорт данных и компонентов в VueОбработка событий и их передача между компонентами VuejsГайд по defineEmits на Vue 3Понимание core функционала Vue и его применениеПонимание и применение Composition API в Vue 3Понимание и работа с компилятором VueКогда и как использовать $emit и call во VueВзаимодействие с внешними API через Axios в Vue
Веб приложения на Vue архитектура и лучшие практикиИспользование Vite для быстрого старта и сборки проектов на Vue 3Работа с URL и ссылками в приложениях на VueРабота с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueИспользование Quasar Framework для разработки на Vue с готовыми UI-компонентамиОбзор популярных шаблонов и стартовых проектов на VueИнтеграция Vue с PHP для создания динамичных веб-приложенийКак организовать страницы и маршруты в проекте на VueNuxt JS и Vue 3 для SSR приложенийСоздание серверных приложений на Vue с помощью Nuxt jsИспользование Vue Native для разработки мобильных приложенийОрганизация и управление индексной страницей в проектах VueИспользование Docker для контейнеризации приложений на VueИнтеграция Vue.js с Django для создания полноценных веб-приложенийСоздание и работа с дистрибутивом build dist Vue приложенийРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияКак исправить ошибку cannot find module vueНастройка и сборка проектов Vue с использованием современных инструментовИнтеграция Vue с Bitrix для корпоративных решенийРазработка административных панелей на Vue js
5 библиотек для создания tree view во VueИнтеграция Tailwind CSS с Vue для современных интерфейсовИнтеграция Vue с серверной частью и HTTPS настройкамиКак обрабатывать async операции с Promise во VueИнтеграция Node.js и Vue.js для разработки приложенийРуководство по интеграции Vue js в NET проектыПримеры использования JSX во VueГайд по импорту и регистрации компонентов на VueМногоязычные приложения на Vue с i18nИнтеграция FLIR данных с Vue5 примеров использования filter во Vue для упрощения разработки3 примера реализации drag-and-drop во Vue
Управление переменными и реактивными свойствами во VueИспользование v for и slot в VueПрименение v-bind для динамической привязки атрибутов в VueУправление пользователями и их данными в Vue приложенияхСоздание и использование UI Kit для Vue приложенийТипизация и использование TypeScript в VuejsИспользование шаблонов в Vue js для построения интерфейсовИспользование Swiper для создания слайдеров в VueРабота со стилями и стилизацией в VueСтруктура и особенности Single File Components SFC в VueРабота со SCSS в проектах на Vue для стилизацииРабота со скроллингом и прокруткой в Vue приложенияхПрименение script setup синтаксиса в Vue 3 для упрощения компонентовИспользование scoped стилей для изоляции CSS в компонентах Vue3 способа улучшить навигацию Vue с push()Обработка запросов и асинхронных операций в VueПонимание и использование provide inject для передачи данных между компонентамиПередача и использование props в Vue 3 для взаимодействия компонентовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsРабота со свойствами компонентов VueУправление параметрами и динамическими данными во VueРабота с lifecycle-хуком onMounted во VueОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование модальных окон modal в Vue приложенияхИспользование методов в компонентах Vue для обработки логикиИспользование метода map в Vue для обработки массивовИспользование хуков жизненного цикла Vue для управления состоянием компонентаРабота с ключами key в списках и компонентах VueОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в VueИспользование хуков жизненного цикла в VueОрганизация сеток и гридов для верстки интерфейсов на VueСоздание и управление формами в VueОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitРабота с динамическими компонентами и данными в Vue3 способа манипулирования DOM на VueРуководство по div во VueИспользование директив в Vue и их расширенные возможностиОсновы и применение директив в VueИспользование директив и их особенности на Vue с помощью defineИспользование компонентов datepicker в Vue для выбора датОрганизация циклов и итераций во VueКак работает компиляция Vue CoreСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в VueИспользование классов в Vue для организации кода и компонентовИспользование директивы checked для управления состоянием чекбоксов в VueГайд на checkbox компонент во VueОтображение данных в виде графиков с помощью Vue ChartСоздание и настройка кнопок в VueСоздание и настройка кнопок в Vue приложенияхРабота с lifecycle-хуками beforeCreate и beforeMount во VueИспользование массивов и методов их обработки в VueИспользование массивов и их обработка в Vue
Использование Vuetify для создания современных интерфейсов на VueИспользование transition во VueТестирование компонентов и приложений на VueПять шагов по настройке SSR в VuejsРабота с teleport для управления DOM во VueИспользование Shadcn UI компонентов с Vue для продвинутых интерфейсовИспользование router-link для навигации в Vue RouterКак использовать require в Vue для динамического импорта модулейРабота с динамическим рендерингом и виртуальным DOM на Vue.jsИспользование ref для управления ссылками и реактивностью в Vue 3Использование Vue Pro и его преимущества для профессиональной разработкиРуководство по nextTick для работы с DOMСоздание и использование компонентов с помощью Vue js и CУправление состоянием и реактивностью через inject и provideДинамическое обновление компонентов и данных на VueГлубокое изучение документации Vue и как эффективно её использоватьИспользование Crystal с Vue для разработкиИспользование вычисляемых свойств для динамического отображения данных на Vue jsОптимизация производительности и предупреждения в Vue
Открыть базу знаний

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

изображение курса

Vue 3 и Pinia

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

TypeScript с нуля

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

Next.js - с нуля

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

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