Валидация форм является важной частью веб-приложений, обеспечивая корректность и полноту данных, вводимых пользователем. Во Vue.js она реализуется через комбинацию реактивных данных, вычисляемых свойств и методов компонентов.
Ключевой механизм — директива v-model, обеспечивающая
двустороннюю привязку данных формы к свойствам
компонента. Например:
data() {
return {
username: '',
email: ''
};
}
<input v-model="username" type="text" />
<input v-model="email" type="email" />
Любые изменения в этих полях автоматически обновляют состояние компонента. Валидация строится поверх этих реактивных свойств.
Для базовой проверки можно использовать вычисляемые свойства:
computed: {
isUsernameValid() {
return this.username.length >= 3;
},
isEmailValid() {
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return re.test(this.email);
},
isFormValid() {
return this.isUsernameValid && this.isEmailValid;
}
}
С помощью этих свойств можно управлять отображением ошибок:
<span v-if="!isUsernameValid">Имя должно содержать минимум 3 символа</span>
<span v-if="!isEmailValid">Некорректный формат email</span>
<button :disabled="!isFormValid">Отправить</button>
Часто необходимо проверять данные на сервере, например уникальность
email. Для этого используются методы компонента и
async/await:
methods: {
async checkEmail() {
if (!this.email) return false;
const response = await fetch(`/api/check-email?email=${this.email}`);
const result = await response.json();
return result.available;
}
}
Вызов метода можно интегрировать в обработчик события
@blur:
<input v-model="email" @blur="validateEmail" />
methods: {
async validateEmail() {
this.emailValid = await this.checkEmail();
}
}
Для сложных форм удобно применять специализированные библиотеки, например Vuelidate или vee-validate, которые позволяют:
$dirty,
$error, $invalid).Пример с Vuelidate:
import { required, minLength, email } from '@vuelidate/validators'
import { useVuelidate } from '@vuelidate/core'
export default {
setup() {
const state = reactive({
username: '',
email: ''
})
const rules = {
username: { required, minLength: minLength(3) },
email: { required, email }
}
const v$ = useVuelidate(rules, state)
return { state, v$ }
}
}
<input v-model="state.username" />
<span v-if="v$.username.$error">Имя некорректно</span>
<input v-model="state.email" />
<span v-if="v$.email.$error">Email некорректен</span>
Во Vue.js ошибки валидации удобно хранить в объекте:
data() {
return {
errors: {}
}
},
methods: {
validateField(field, value) {
switch(field) {
case 'username':
this.errors.username = value.length < 3 ? 'Имя слишком короткое' : '';
break;
case 'email':
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
this.errors.email = !re.test(value) ? 'Неверный email' : '';
break;
}
}
}
Привязка к форме:
<input v-model="username" @input="validateField('username', username)" />
<span>{{ errors.username }}</span>
<input v-model="email" @input="validateField('email', email)" />
<span>{{ errors.email }}</span>
Валидацию можно выносить в отдельные компоненты или миксины для повторного использования:
export const validationMixin = {
methods: {
required(value) {
return value ? '' : 'Поле обязательно для заполнения';
},
minLength(value, length) {
return value.length >= length ? '' : `Минимум ${length} символов`;
}
}
}
Компонент:
mixins: [validationMixin],
methods: {
validateUsername() {
this.errors.username = this.required(this.username) || this.minLength(this.username, 3);
}
}
С использованием Composition API можно объединять состояние, методы и правила в единый объект:
import { reactive, computed } from 'vue'
export default {
setup() {
const form = reactive({
username: '',
email: '',
errors: {}
})
const validate = () => {
form.errors.username = form.username.length < 3 ? 'Имя слишком короткое' : '';
const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
form.errors.email = !re.test(form.email) ? 'Email некорректен' : '';
}
const isFormValid = computed(() => !form.errors.username && !form.errors.email)
return { form, validate, isFormValid }
}
}
В шаблоне:
<input v-model="form.username" @input="validate" />
<span>{{ form.errors.username }}</span>
<input v-model="form.email" @input="validate" />
<span>{{ form.errors.email }}</span>
<button :disabled="!isFormValid">Отправить</button>
В реальных приложениях часто используют комбинацию:
Такой подход обеспечивает надежность, читаемость кода и легкость расширения форм.