如何将自定义组件 vee-validate 与 v-model 一起使用?

how can I use custom component vee-validate with v-model?

我有一个名为 TextInput 的组件。我需要在此组件中发送带有@input 事件的 v-model,但我也希望它使用 vee-validate 进行验证。

但是当我在 usefield 中使用 handleChange 函数时,它会进行验证。但是这次我无法使用 v-model 发送值。

当我如下做的时候,在我调用的组件中使用v-model时可以使用v-model,但是它不做验证过程

<template>
  <div
      class="TextInput"
      :class="{ 'has-error': !!errorMessage, success: meta.valid }"
  >
    <label :for="name">{{ label }}</label>
    <input
        :name="name"
        :type="type"
        :id="name"
        :value="modelValue"
        :placeholder="placeholder"
        @input="handleChange"

        @blur="handleBlur"
        v-bind="$attrs"
    />

    <p class="help-message" v-show="errorMessage || meta.valid">
      {{ errorMessage || successMessage }}
    </p>
  </div>
</template>

<script>
import { useField } from "vee-validate";

export default {
  props: {
    type: {
      type: String,
      default: "text",
    },
    modelValue:String,
    value: {
      type: String,
      default: "",
    },
    name: {
      type: String,
      required: true,
    },
    label: {
      type: String,
      required: true,
    },
    successMessage: {
      type: String,
      default: "",
    },
    placeholder: {
      type: String,
      default: "",
    },
  },
  emits: ['update:modelValue'],
  setup(props,{emit}) {

    const handleChange = (event) =>{
      emit('update:modelValue', event.target.value);
    }
    const {

      errorMessage,
      handleBlur,
      meta,
    } = useField(props.name, undefined, {
      initialValue: props.value,
    });

    return {
      handleChange,
      handleBlur,
      errorMessage,
      meta,
    };
  },
};
</script>

当您按如下方式执行时,它不会发送 v-model,但会正确执行验证。

<template>
  <div
    class="TextInput"
    :class="{ 'has-error': !!errorMessage, success: meta.valid }"
  >
    <label :for="name">{{ label }}</label>
    <input
      :name="name"
      :id="name"
      :type="type"
      :value="inputValue"
      :placeholder="placeholder"
      @input="handleChange"
      @blur="handleBlur"
    />

    <p class="help-message" v-show="errorMessage || meta.valid">
      {{ errorMessage || successMessage }}
    </p>
  </div>
</template>

<script>
import { useField } from "vee-validate";

export default {
  props: {
    type: {
      type: String,
      default: "text",
    },
    value: {
      type: String,
      default: "",
    },
    name: {
      type: String,
      required: true,
    },
    label: {
      type: String,
      required: true,
    },
    successMessage: {
      type: String,
      default: "",
    },
    placeholder: {
      type: String,
      default: "",
    },
  },
  setup(props) {
    const {
      value: inputValue,
      errorMessage,
      handleBlur,
      handleChange,
      meta,
    } = useField(props.name, undefined, {
      initialValue: props.value,
    });

    return {
      handleChange,
      handleBlur,
      errorMessage,
      inputValue,
      meta,
    };
  },
};
</script>

如何以相同的方式发送验证和 v-model?

您需要将 valueProp 参数添加到 useField 构造函数并将属性 value 更改为 modelValue。您还需要为输入事件引入一个处理程序,该处理程序将从 useField 调用 handleChange 并发出适当的 update:modelValue 事件,以便 v-model 绑定起作用。

这将允许验证和 v-model 绑定工作。我对以下示例进行了更改:

<template>
  <div
    class="TextInput"
    :class="{ 'has-error': !!errorMessage, success: meta.valid }"
  >
    <label :for="name">{{ label }}</label>
    <input
      :name="name"
      :id="name"
      :type="type"
      :value="inputValue"
      :placeholder="placeholder"
      @input="onInput($event)"
      @blur="handleBlur"
    />

    <p class="help-message" v-show="errorMessage || meta.valid">
      {{ errorMessage || successMessage }}
    </p>
  </div>
</template>

<script>
import { useField } from "vee-validate";

export default {
  props: {
    type: {
      type: String,
      default: "text",
    },
    modelValue: {
      type: String,
      default: "",
    },
    name: {
      type: String,
      required: true,
    },
    label: {
      type: String,
      required: true,
    },
    successMessage: {
      type: String,
      default: "",
    },
    placeholder: {
      type: String,
      default: "",
    },
  },
  setup(props, {emit}) {
    const {
      value: inputValue,
      errorMessage,
      handleBlur,
      handleChange,
      meta,
    } = useField(props.name, undefined, {
      initialValue: props.modelValue,
      valueProp: props.modelValue
    });

    const onInput = (event) => {
      handleChange(event, true)
      emit('update:modelValue', event.target.value)
    }

    return {
      onInput,
      handleChange,
      handleBlur,
      errorMessage,
      inputValue,
      meta,
    };
  },
};
</script>