Лекции
October 10, 2020

Валидация форм. 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.