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.