Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як показати у Vue-застосунку помилки валідації Laravel з відповіді 422 без Inertia?

Коли валідація Laravel не проходить у запиті, що очікує JSON, сервер відповідає статусом 422 і тілом:

{
  "message": "The email has already been taken. (and 1 more error)",
  "errors": {
    "email": ["The email has already been taken."],
    "items.0.qty": ["The items.0.qty field must be at least 1."]
  }
}

Ключі - назви полів, для вкладених даних - через крапку. Значення - масив повідомлень.

Обробка в Vue:

<script setup lang="ts">
import { reactive, ref } from 'vue'
import axios from 'axios'

const form = reactive({ name: '', email: '' })
const errors = ref<Record<string, string[]>>({})

async function submit() {
  errors.value = {}
  try {
    await axios.post('/api/users', form, { headers: { Accept: 'application/json' } })
  } catch (e) {
    if (axios.isAxiosError(e) && e.response?.status === 422) {
      errors.value = e.response.data.errors
      return
    }
    throw e   // інші помилки - далі, до глобального обробника
  }
}
</script>

<template>
  <input v-model="form.email" :aria-invalid="!!errors.email" />
  <p v-if="errors.email" class="error">{{ errors.email[0] }}</p>
</template>

З fetch код схожий, але fetch не кидає виняток на 422 - перевіряти треба response.status самостійно, а тіло читати через await response.json().

Важливі деталі:

  • заголовок Accept: application/json обов'язковий: без нього Laravel вважає запит звичайним переходом форми й відповідає редиректом назад з помилками в сесії, а не JSON;
  • очищайте помилки перед новою відправкою, інакше старі повідомлення лишаються на екрані;
  • прибирайте помилку поля при його зміні - watch на поле чи очищення в @input - користувач бачить, що виправлення прийнято;
  • вкладені ключі (items.0.qty) треба зіставити з полем у списку - зберігайте помилки за тим самим шаблоном назв;
  • 401 і 419 - це не валідація: 401 - не автентифікований, 419 - прострочений CSRF-токен (для SPA на Sanctum спершу потрібен запит до /sanctum/csrf-cookie).

Типізація: опишіть тип відповіді 422 ({ message: string; errors: Record<string, string[]> }) один раз і використовуйте в усіх формах - через спільну функцію чи composable useServerErrors().

Докладніше в документації: Axios: обробка помилок

Схожі питання