Работа с сервером во Vue 3: получение и отправка данных через Axios

Современные веб-приложения редко существуют сами по себе — почти всегда им нужно получать или отправлять данные на сервер.
Во Vue 3 это можно делать просто и элегантно, особенно если использовать библиотеку Axios и управлять данными через Pinia.

В этой главе мы научимся работать с HTTP-запросами: загружать данные, добавлять, обновлять и удалять их — всё в реактивном и удобном стиле Vue 3.

🧩 1. Установка и подключение Axios

Axios — это популярная библиотека для работы с HTTP-запросами. Она проста, поддерживает промисы и хорошо интегрируется с Vue.

Установим её командой:

npm install axios

После установки мы сможем импортировать Axios в любом модуле и использовать его методы для общения с сервером.

⚙️ 2. Создание Pinia-хранилища для работы с API

Чтобы хранить данные, полученные с сервера, удобно использовать Pinia.
Создадим хранилище useArticleStore.js, которое будет отвечать за загрузку и управление статьями.

// stores/useArticleStore.js
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
import axios from 'axios'

export const useArticleStore = defineStore('article', () => {
  // реактивные данные
  const articles = ref([])
  const loading = ref(false)
  const error = ref(null)

  // базовый URL API
  const API_URL = 'https://jsonplaceholder.typicode.com/posts'

  // 📦 Получение всех статей
  const fetchArticles = async () => {
    loading.value = true
    error.value = null
    try {
      const { data } = await axios.get(API_URL)
      articles.value = data
    } catch (err) {
      error.value = err.message || 'Ошибка при загрузке данных'
    } finally {
      loading.value = false
    }
  }

  // 🔍 Получение статьи по ID
  const fetchArticleById = async (id) => {
    try {
      const { data } = await axios.get(`${API_URL}/${id}`)
      return data
    } catch (err) {
      error.value = err.message
      return null
    }
  }

  // ➕ Добавление новой статьи
  const addArticle = async (newArticle) => {
    try {
      const { data } = await axios.post(API_URL, newArticle)
      articles.value.push(data)
    } catch (err) {
      console.error('Ошибка при добавлении статьи:', err)
    }
  }

  // ♻️ Обновление статьи
  const updateArticle = async (id, updatedArticle) => {
    try {
      const { data } = await axios.put(`${API_URL}/${id}`, updatedArticle)
      const index = articles.value.findIndex(a => a.id === id)
      if (index !== -1) articles.value[index] = data
    } catch (err) {
      console.error('Ошибка при обновлении статьи:', err)
    }
  }

  // 🗑️ Удаление статьи
  const deleteArticle = async (id) => {
    try {
      await axios.delete(`${API_URL}/${id}`)
      articles.value = articles.value.filter(a => a.id !== id)
    } catch (err) {
      console.error('Ошибка при удалении статьи:', err)
    }
  }

  // Вычисляемое свойство
  const totalArticles = computed(() => articles.value.length)

  return {
    articles,
    loading,
    error,
    totalArticles,
    fetchArticles,
    fetchArticleById,
    addArticle,
    updateArticle,
    deleteArticle
  }
})

🧠 3. Использование данных из хранилища в компоненте

Теперь подключим наше хранилище к компоненту и выведем список статей.

<!-- components/ArticleList.vue -->
<template>
  <section>
    <h2>Список статей</h2>

    <div v-if="store.loading">Загрузка данных...</div>
    <div v-else-if="store.error">Ошибка: {{ store.error }}</div>

    <ul v-else>
      <li v-for="article in store.articles" :key="article.id">
        {{ article.title }}
      </li>
    </ul>
  </section>
</template>

<script setup>
import { onMounted } from 'vue'
import { useArticleStore } from '@/stores/useArticleStore'

const store = useArticleStore()

onMounted(() => {
  store.fetchArticles()
})
</script>

Теперь при монтировании компонента Vue автоматически выполнит запрос к серверу и отобразит список статей.
Если данные ещё загружаются — покажется сообщение “Загрузка данных...”, а при ошибке — текст ошибки.

🧩 4. Обработка ошибок и загрузки

При работе с сервером важно учитывать три состояния:

  • Загрузка — данные ещё не получены;

  • Успех — данные успешно загружены;

  • Ошибка — запрос не удался.

В нашем примере эти состояния реализованы с помощью реактивных переменных:

const loading = ref(false)
const error = ref(null)

Vue автоматически обновляет интерфейс, когда значения этих переменных меняются — это и есть сила реактивности.

🏁 5.Заключение

Теперь ты умеешь:

  • Подключать и использовать Axios;

  • Делать GET, POST, PUT и DELETE запросы;

  • Управлять состоянием загрузки и ошибок;

  • Интегрировать всё это в Pinia и Vue-компоненты.