vee-validate 是否与第三方 UI 组件一起工作,例如Primevue 的?

Does vee-validate work with third-party UI components, e.g. of Primevue?

我正在使用 vee-validate v4.0、带有 TypeScript 的 vue (v3) 组件以及来自 Primevue 和 Ionic 的 UI 组件。对简单输入字段的验证工作正常:

<template> 
...
<Field
  v-slot="{ field }"
  v-model="username"
  :rules="isRequired"
  name="username"
>
  <IonInput
    v-bind="field"
    type="text"
  />
</Field>
<ErrorMessage
  name="username"
  class="error"
/>
...
</template>

<script lang="ts">
...
 methods: {
    isRequired (value: string) {
      if (!value) {
        return 'This field is required'
      }
      return true
    }
  }
...
</script>

将相同的方法应用于 Primevue 的 Dropdown 元素失败:

<Field
  v-slot="{ field }"
  v-model="campaign"
  name="campaign"
  :rules="isRequired"
>
  <Dropdown
    :options="campaigns"
    option-value="id"
    option-label="name"
    placeholder="Choose a campaign"
    v-bind="field"
  />
</Field>
<ErrorMessage
  name="campaign"
  class="error"
/>

验证按预期工作,但打开下拉菜单会导致错误消息:

你知道怎么解决吗?是否有 vee-validate 如何处理更复杂的字段(如下拉列表或多选元素)的示例?

这可以通过侦听 input/change 事件并在 <Field> 和(在这种特殊情况下 Primevue 的)<Dropdown> 之间传递数据来解决,如下所示:

<Form v-slot="{ errors }" @submit="saveAndProceed()">
...

  <Field
    v-slot="{ field }"
    v-model="campaign"
    name="campaign"
    value="value"
    :rules="isRequired"
  >
    <Dropdown
      :options="campaigns"
      option-value="id"
      option-label="name"
      placeholder="Choose a campaign"
      :model-value="field.value"
      :class="{ 'p-invalid': errors.campaign }"
      @input="field.onInput.forEach((fn) => fn($event.value))"
      @change="field.onChange.forEach((fn) => fn($event.value))"
    />
    <ErrorMessage
      name="campaign"
      class="error"
    />
  </Field>
...
</Form>

另请与以下其他事件(onBlur 等)的参考资料进行比较:

您需要将 @update:modelValue="handleChange" 添加到下拉列表中:

<Field
  v-slot="{ field, handleChange }"
  v-model="campaign"
  name="campaign"
  :rules="isRequired"
>
  <Dropdown
    :options="campaigns"
    option-value="id"
    option-label="name"
    placeholder="Choose a campaign"
    v-bind="field"
    @update:modelValue="handleChange"
  />
</Field>
<ErrorMessage
  name="campaign"
  class="error"
/>