如何修改我的自定义输入组件以使用 vee-validate?

How to modify my custom input component to work with vee-validate?

我在我的 Vue 项目中创建了一个输入组件,我在我的表单中使用了这个组件。我想使用 vee-validate 来验证我的输入。

首先,我尝试像正常输入一样验证我的组件,但在显示错误消息和检查 Vue Devtools 失败后,我发现错误仅限于输入组件。 (虽然有两个名为 "errors" 和 "fields" 的计算属性我的所有组件都可以访问,从根到输入组件本身。)

然后我检查了vee-validate docs and tried to use Validation Provider and Validation Observer. These two components are too confusing to me and I couldn't figure out how to use them even after checking this medium article。我不知道这些组件是如何使用作用域插槽的。

我希望能够验证父级中的输入组件,并在表单上方的父级中显示它们的错误消息。 (有或没有 Validation Observer and/or Validation Provider)。任何方法表示赞赏。

这是我的输入组件:

<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: 我在全球注册了Validation Observer和Validation Provider

尝试以下 this example:

<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 的本地反应项中。通常您不想更改道具的值,尽管它可能适用于这种简单的情况。 Re-read One-Way Data Flow 了解详情。