Как изменить мой пользовательский компонент ввода для работы с vee-validate? - PullRequest
1 голос
/ 20 июня 2019

Я создал компонент ввода в своем проекте Vue, и я использую этот компонент внутри своих форм. Я хочу использовать vee-validate для проверки моих входных данных.

Сначала я попытался проверить свой компонент так же, как обычный ввод, но после сбоя при отображении сообщений об ошибках и проверке Vue Devtools я выяснил, что ошибки относятся к компоненту ввода. (хотя есть два вычисляемых свойства с именами «ошибки» и «поля», к которым имеют доступ все мои компоненты, от корневого до самого компонента ввода.)

Затем я проверил vee-validate docs и попытался использовать Поставщик проверки и Validation Observer . Эти два компонента слишком запутаны для меня, и я не мог понять, как их использовать, даже после проверки этой средней статьи . Я не знаю, как эти компоненты используют ограниченные слоты.

Я хочу иметь возможность проверять входные компоненты в родительском элементе, а также отображать их сообщения об ошибках в родительском элементе над формой. (с или без наблюдателя проверки и / или поставщика проверки). Любой подход приветствуется.

Это мой компонент ввода:

<template>
  <div class="info-input-control">
    <div class="info-input-icon">
      <slot name="icon"><span uk-icon="icon: pencil; ratio: 1.4"></span></slot>
    </div>

    <input :id="id" :type="type" :value="value" :name="name"
           v-validate="validations || ''"
           @keyup.enter="$emit('enter')"
           @focus="isActive = true"
           @blur="isActive = value.length > 0"
           @input="$emit('input', $event.target.value)" :key="name">
    <label :for="id" :class="{'info-input-label': true, 'is-active': isActive}">{{label}}</label>

  </div>
</template>

<script>
    export default {
        name: 'InfoTextInput',
        props: {
            id: String,
            label: String,
            ltr: Boolean,
            name: {
                type: String,
                required: true
            },
            type: {
                type: String,
                required: true,
                validator: function (value) {
                    return ['text', 'password', 'email'].indexOf(value) !== -1
                }
            },
            validations: Object,
            value: String
        },
        data() {
            return {
                isActive: false
            }
        },
        mounted() {
            this.isActive = this.value.length > 0
        }
    }
</script>

и это минимальная версия моей формы с одним входным компонентом:

<form action="#" @submit.prevent="userLogin">
    <div class="uk-text-danger">
        <span>Errors: </span>
        <span>{{errors.first('mobile')}}</span>
    </div>

    <div class="uk-flex uk-flex-center">
        <div class="uk-width-medium">
            <info-text-input type="text" id="user-login-phone" label="Mobile" name="mobile" ltr v-model="login.mobile" :validations="mobileValidations" key="login-mobile">
                <template v-slot:icon>
                    <span uk-icon="icon: phone; ratio: 1.4"></span>
                </template>
            </info-text-input>
        </div>
    </div>
</form>

P.S .: Я зарегистрировал наблюдателя и поставщика валидации по всему миру.

1 Ответ

1 голос
/ 21 июня 2019

Попробуйте выполнить этот пример :

<template>
  <div class="info-input-control">
    <div class="info-input-icon">
      <slot name="icon"><span uk-icon="icon: pencil; ratio: 1.4"></span></slot>
    </div>

    <input :id="id" :type="type" :name="name"
           v-model="localValue"
           v-validate="validations || ''"
           @keyup.enter="$emit('enter')"
           @focus="isActive = true"
           @blur="isActive = value.length > 0"
           @input="$emit('input', localValue)" :key="name">
    <label :for="id" :class="{'info-input-label': true, 'is-active': isActive}">{{label}}</label>

  </div>
</template>

<script>
    export default {
        $_veeValidate: {
           value() {
               return this.localValue;
           },
           name() {
              return this.name;
           }
        },
        name: 'InfoTextInput',
        props: {
            id: String,
            label: String,
            ltr: Boolean,
            name: {
                type: String,
                required: true
            },
            type: {
                type: String,
                required: true,
                validator: function (value) {
                    return ['text', 'password', 'email'].indexOf(value) !== -1
                }
            },
            validations: Object,
            value: String
        },
        data() {
            return {
                localValue: this.value,
                isActive: false
            }
        },
        mounted() {
            this.isActive = this.localValue.length > 0
        }
    }
</script>

Я добавил только пару вещей - секцию $_veeValidate в скрипте.Я также изменил ваш компонент, чтобы использовать опору value, но сохранил изменения в локальном реактивном элементе под названием localValue.Как правило, вы не захотите менять значение реквизита, хотя это может сработать в этом простом случае.Перечитайте Односторонний поток данных для подробностей.

...