JAVASCRIPT

Vue 3 Composable for Basic Form Input Validation

Create a reusable Vue 3 composable to easily implement client-side form input validation, checking for common rules like required fields and minimum length.

// composables/useValidation.js
import { ref, computed } from 'vue';

export function useValidation(value, rules) {
  const isValid = ref(true);
  const errorMessage = ref('');

  const validate = () => {
    isValid.value = true;
    errorMessage.value = '';

    for (const rule of rules) {
      if (rule.name === 'required' && !value.value) {
        isValid.value = false;
        errorMessage.value = rule.message || 'This field is required.';
        break;
      }
      if (rule.name === 'minLength' && value.value.length < rule.length) {
        isValid.value = false;
        errorMessage.value = rule.message || `Minimum length is ${rule.length} characters.`;
        break;
      }
      // Add more rules as needed
    }
  };

  // Re-validate whenever the value changes
  // This is a simple watcher, for more complex scenarios,
  // consider explicit calling or deep watching.
  // watch(value, validate, { immediate: true }); // Can uncomment if validation on mount is desired

  const hasError = computed(() => !isValid.value);

  return {
    isValid,
    errorMessage,
    hasError,
    validate
  };
}

// App.vue (example usage)
<template>
  <form @submit.prevent="submitForm">
    <div>
      <label for="username">Username:</label>
      <input type="text" id="username" v-model="username" @blur="usernameValidator.validate" />
      <p v-if="usernameValidator.hasError" class="error-message">{{ usernameValidator.errorMessage }}</p>
    </div>

    <div>
      <label for="password">Password:</label>
      <input type="password" id="password" v-model="password" @blur="passwordValidator.validate" />
      <p v-if="passwordValidator.hasError" class="error-message">{{ passwordValidator.errorMessage }}</p>
    </div>

    <button type="submit">Submit</button>
  </form>
</template>

<script setup>
import { ref } from 'vue';
import { useValidation } from './composables/useValidation';

const username = ref('');
const password = ref('');

const usernameValidator = useValidation(username, [
  { name: 'required', message: 'Username is required.' },
  { name: 'minLength', length: 3, message: 'Username must be at least 3 characters.' }
]);

const passwordValidator = useValidation(password, [
  { name: 'required', message: 'Password is required.' },
  { name: 'minLength', length: 6, message: 'Password must be at least 6 characters.' }
]);

const submitForm = () => {
  usernameValidator.validate();
  passwordValidator.validate();

  if (!usernameValidator.hasError.value && !passwordValidator.hasError.value) {
    alert('Form submitted successfully!');
    // Process form data
  } else {
    alert('Please correct the form errors.');
  }
};
</script>

<style scoped>
.error-message {
  color: red;
  font-size: 0.9em;
  margin-top: 5px;
}
div {
    margin-bottom: 15px;
}
</style>
How it works: This snippet provides a Vue 3 composable, `useValidation`, for handling basic client-side form input validation. It takes a `ref` (the input's value) and an array of rules. The composable exposes `isValid`, `errorMessage`, `hasError` (a computed property), and a `validate` function. Components can integrate this composable with input fields, calling `validate` on events like `blur` or during form submission, providing immediate feedback to the user without server roundtrips.

Need help integrating this into your project?

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

Hire DigitalCodeLabs