In this example, we will show how to validate Vue.js form and display error messages from Laravel. Let's say we have a simple form to collect the user's name and email for our mailing list.
For this demonstration, we used Laravel Breeze starter kit with Vue preset.
Request validation and API Controller
Create the MailingListRequest
class with validation rules for name and email.
app/Http/Requests/MailingListRequest.php
namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class MailingListRequest extends FormRequest{ public function authorize(): bool { return true; } public function rules(): array { return [ 'name' => 'required|string', 'email' => 'required|email', ]; }}
Then make API Controller. It will validate fields using MailingListRequest
and return a success message if validation passes.
app/Http/Controllers/Api/MailingListController.php
namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller;use App\Http\Requests\MailingListRequest; class MailingListController extends Controller{ public function store(MailingListRequest $request) { // process data return response()->json(['message' => 'Thank you']); }}
Define API route.
routes/api.php
use App\Http\Controllers\Api\MailingListController; Route::post('/mailing-list', [MailingListController::class, 'store']);
Now, we can make a Vue form to submit to the API endpoint. If the data presented is invalid, the response will have a 422 response status, and Axios will throw an error. We catch the error and assign error messages from the response to the errors
variable to display those messages in the form.
resources/js/Pages/Subscribe.vue
<script setup>import { reactive, ref } from 'vue'; const errors = ref({})const success = ref('') const form = reactive({ name: '', email: ''}); function submit() { axios.post('/api/mailing-list', form) .then(response => success.value = response.data.message) .catch(error => { if (error.response.status === 422) { errors.value = error.response.data.errors } })}</script> <template> <div class="bg-gray-50 min-h-screen pt-12"> <div class="max-w-md mx-auto bg-white rounded shadow-sm p-6 text-gray-900"> <span class="text-green-600" v-if="success">{{ success }}</span> <form v-else class="flex flex-col space-y-4" @submit.prevent="submit" novalidate> <div class="flex flex-col space-y-2"> <label>Name</label> <input type="text" class="rounded" v-model="form.name"> <span class="text-red-600" v-if="errors?.name">{{ errors.name[0] }}</span> </div> <div class="flex flex-col space-y-2"> <label>Email</label> <input type="email" class="rounded" v-model="form.email"> <span class="text-red-600" v-if="errors?.email">{{ errors.email[0] }}</span> </div> <button class="bg-gray-500 text-white rounded px-3 py-2"> Subscribe </button> </form> </div> </div></template>
When validation passes, a success message will be displayed instead of a form.
No comments or questions yet...