Валидация форм. Vuelidate. Computed. Маски ввода. Директивы. Своя фриланс биржа #11
Привет! Сегодня мы займёмся валидацией форм на фронтенде. Для этого будем использовать библиотеку Vuelidate.
Установка и настройка
Для начала давайте её установим:
$ npm i vuelidate -S
Подробно почитать и потыкаться в примеры можно тут.
Дальше мы должны импортировать её в src/main.js:
// main.js import Vuelidate from 'vuelidate'; Vue.use(Vuelidate);
Теперь нужно импортировать библиотеку в компоненту auth/SignUp.vue
:
... <script> import { required } from 'vuelidate/lib/validators' ... </script>
Заведём, подобно объекту methods
объект validations
:
validations: { username: { required }, password: { required }, repeatPassword: { required }, phone: { required } }
Для начала, мы импортируем и расставляет только атрибут required
, чтобы удостовериться, что всё точно работает так, как нам хочется.
По моей задумке, пока форма не валидна, кнопка "Регистрация" должна быть недоступна для клика, то есть переведена в состояние disabled
. Для того, чтобы динамически это состояние менять, будем использовать вычисляемые свойства (computed):
computed: { formValid() { return this.$v.$invalid } }
Их мы так же добавляем, как и methods
, validations
в метод data()
.
Вычисляемые свойства нужны для того, чтобы при изменении возвращаемого ими значения можно было поменять что-то на странице динамически.
Добавляем атрибут disabled, значение которого будет получаться из вычисляемого свойства formValid:
<b-button variant="primary" type="submit" :disabled="formValid">Регистрация</b-button>
Теперь до заполнения всей формы, кнопка должна быть неактивна:
После заполнения всё должно само поменяться:
Валидация пароля
Добавим валидацию для пароля на минимальную длину и условие, чтобы password
и repeatPassword
должны иметь одинаковые значения:
1) Импортируем minLength
и sameAs
:
import { required, minLength, sameAs } from 'vuelidate/lib/validators'
2) Дописываем нужные значения для валидации:
password: { required, minLength: minLength(8) }, repeatPassword: { required, sameAs: sameAs('password') },
Ввод номера телефона по маске
$ npm i vue-imask -S
Импортируем ImaskDirective
в компоненту auth/SignUp.vue
:
import {IMaskDirective} from 'vue-imask';
Заводим объект directives
внутри data ()
:
directives: { imask: IMaskDirective }
В data ()
заводим модель phoneNumberMask
для использования маски:
phoneNumberMask: { mask: '+{7} (000) 000-00-00' }
Добавляем к нашему полю для ввода номера телефона директиву v-imask
, слушателей событий complete
, accept
, keypress
, свойство maxlength
:
<b-input v-model="phone" type="text" id="phone" v-imask="phoneNumberMask" placeholder="+7(921)123-45-67" @keypress="isNumber" @accept="onAccept" @complete="onComplete" maxlength="16"></b-input>
onAccept(e) { const maskRef = e.detail this.phone = maskRef.value }, onComplete(e) { const maskRef = e.detail this.userPhone = maskRef.unmaskedValue }, isNumber(e) { let regex = /[0-9]/ if (!regex.test(e.key)) { e.returnValue = false; if (e.preventDefault) e.preventDefault(); } }
Максимальная длина равна 16, потому что длина строки +7(921)123-45-67
равна 16. Функцией isNumber
мы проверяем, чтобы вводимые символы были только цифрами. В методе onAccept
мы обновляем значение в соответствии с введённым, в методе onComplete
мы записываем итоговое значение в v-model
userPhone
.