JAVASCRIPT

General Form Validation with Vue 3 Composition API

Implement robust and flexible form validation in Vue 3 applications using the Composition API, reactive state, and computed properties for managing validation rules.

// components/RegistrationForm.vue
<template>
  <form @submit.prevent="submitForm">
    <h2>Register</h2>
    <div>
      <label for="username">Username:</label>
      <input type="text" id="username" v-model="form.username" @blur="validateField('username')">
      <p v-if="errors.username" class="error">{{ errors.username }}</p>
    </div>

    <div>
      <label for="email">Email:</label>
      <input type="email" id="email" v-model="form.email" @blur="validateField('email')">
      <p v-if="errors.email" class="error">{{ errors.email }}</p>
    </div>

    <div>
      <label for="password">Password:</label>
      <input type="password" id="password" v-model="form.password" @blur="validateField('password')">
      <p v-if="errors.password" class="error">{{ errors.password }}</p>
    </div>

    <button type="submit" :disabled="!isFormValid">Register</button>

    <p v-if="submissionMessage" :class="{ 'success': submissionSuccess, 'error': !submissionSuccess }">{{ submissionMessage }}</p>
  </form>
</template>

<script setup>
import { reactive, computed, ref } from 'vue';

const form = reactive({
  username: '',
  email: '',
  password: ''
});

const errors = reactive({
  username: '',
  email: '',
  password: ''
});

const submissionMessage = ref('');
const submissionSuccess = ref(false);

const validateField = (fieldName) => {
  errors[fieldName] = ''; // Clear previous error
  switch (fieldName) {
    case 'username':
      if (!form.username) {
        errors.username = 'Username is required.';
      } else if (form.username.length < 3) {
        errors.username = 'Username must be at least 3 characters.';
      }
      break;
    case 'email':
      if (!form.email) {
        errors.email = 'Email is required.';
      } else if (!/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/.test(form.email)) {
        errors.email = 'Invalid email format.';
      }
      break;
    case 'password':
      if (!form.password) {
        errors.password = 'Password is required.';
      } else if (form.password.length < 6) {
        errors.password = 'Password must be at least 6 characters.';
      }
      break;
  }
};

const validateAllFields = () => {
  validateField('username');
  validateField('email');
  validateField('password');
  return Object.values(errors).every(error => error === '');
};

const isFormValid = computed(() => {
  return form.username !== '' && form.email !== '' && form.password !== '' && Object.values(errors).every(error => error === '');
});

const submitForm = () => {
  submissionMessage.value = '';
  if (validateAllFields()) {
    // Simulate API call
    console.log('Form submitted:', form);
    submissionSuccess.value = true;
    submissionMessage.value = 'Registration successful!';
    // Reset form after successful submission if needed
    // form.username = ''; form.email = ''; form.password = '';
  } else {
    console.log('Form has errors:', errors);
    submissionSuccess.value = false;
    submissionMessage.value = 'Please correct the errors.';
  }
};
</script>

<style scoped>
form {
  max-width: 400px;
  margin: 50px auto;
  padding: 20px;
  border: 1px solid #ccc;
  border-radius: 8px;
  background-color: #f9f9f9;
}
div {
  margin-bottom: 15px;
}
label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}
input[type="text"],
input[type="email"],
input[type="password"] {
  width: 100%;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  box-sizing: border-box;
}
.error {
  color: red;
  font-size: 0.9em;
  margin-top: 5px;
}
button {
  padding: 10px 15px;
  background-color: #4CAF50;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}
button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}
.success {
  color: green;
}
</style>
How it works: This snippet demonstrates a general form validation pattern in Vue 3 using the Composition API. Form data and validation errors are managed with `reactive` objects. The `validateField` function checks individual fields, and `validateAllFields` ensures all fields meet criteria before submission. A `computed` property, `isFormValid`, dynamically checks if the form can be submitted, enabling/disabling the button. Error messages are conditionally displayed, providing immediate user feedback.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs