【问题标题】:How to use vee-validate in a parent-child relationship如何在父子关系中使用 vee-validate
【发布时间】:2020-03-03 04:25:21
【问题描述】:

我有几个组件需要验证。问题是输入在子组件中,而提交按钮在父组件中,就像这样

父组件.js

<ValidationObserver v-slot="{ passes }"> 
     <form @submit.prevent="passes(someSubmitFunction)">
         <ChildComponent />
     </form>
</ValidationObserver>

ChildComponent.js

     <ValidationProvider rules="required" v-slot="{ errors }" name="vendorName">
         <el-input />
      </ValidationProvider>

我在这里做错了什么?

【问题讨论】:

    标签: vue.js vee-validate


    【解决方案1】:

    您可以像这样在创建的钩子中通过父组件验证器覆盖 chid 组件验证器的实例。

    created() {
     this.$validator = this.$parent.$validator
    }
    

    注意:如果你使用mounted,它不会起作用,因为在DOM渲染之前必须完成替换。

    【讨论】:

      【解决方案2】:

      幸运的是,有一种模式可以在父组件和子组件之间共享验证器范围!您可以inject 验证器从父级进入子级,以便它们使用相同的实例。这意味着您可以使用 this.$validator.validate() 验证来自父级的子输入

      文档: http://vee-validate.logaretm.com/v2/concepts/injections.html

      【讨论】:

      • v3 的解决方案是什么?在 v3 中,不再有 $validator
      • @LiangWang 你必须使用 ValidationProvider 和 ValidationObserver。这就是我所知道的一切,我选择继续使用 v2,因为它更简单。
      • @LiangWang 一年后在寻找 v4 解决方案时看到了这个,在下面添加了一个建议的答案......所以如果你还在摸不着头脑,那就不要再看了?
      【解决方案3】:

      对于像我这样的人,将来会来这里寻求指导,使用 vee-validatev4 以及 Vue3 Composition APITypescript,我想建议这个答案。它的工作原理是将 useForm 中的每个 validate 方法添加到数组中,然后在提交表单时,它将循环遍历数组以确保所有验证器异步传递。

      formAggregator.ts

      import { InjectionKey, provide, ref } from "vue";
      
      type ValidatorMethodType = () => Promise<{ valid: boolean }>;
      
      export const AddValidatorKey: InjectionKey<
        (validator: ValidatorMethodType) => void
      > = Symbol("AddValidatorKey");
      
      export function useValidationAggregator() {
        const validators = ref<ValidatorMethodType[]>([]);
      
        // used by components to add validators to the array
        const register = (validator: ValidatorMethodType) => {
          validators.value.push(validator);
        };
      
        // provide this aggregator to components
        provide(AddValidatorKey, register);
      
        // run all validators
        const validateAll = async () => {
          return Promise.all(validators.value.map((v) => v()));
        };
      
        return {
          validateAll,
          register,
        };
      }
      

      ParentComponent.vue

      <template>
      <form @submit.prevent="onSubmit">
          <ChildComponent />
         <button type="submit" :disabled="inSubmit">Submit</button>
      </form>
      </template>
      <script setup>
      import useValidationAggregator from "./formAggregator.ts"
      const { validateAll } = useValidationAggregator();
      // note: you can use register() to also add validator from the parent component
      
      const inSubmit = ref(false);
      const onSubmit = async () => {
         try {
            inSubmit.value = true;
      
            // run all form validators
            const results = await validateAll();
      
            // ensure all are valid
            if (results.some((r) => !r.valid)) {
               return;
            }
      
            // todo: post form or whatever you need after validation passes
         } finally {
            inSubmit.value = false;
         }
      }
      </script>
      

      ChildComponent.vue

      <template>
         <!-- some validated fields -->
      </template>
      <script setup>
      import { AddValidatorKey } from "./formAggregator.ts"
      
      const { validate } = useForm({ ... setup validated fields ... });
      
      // add this component's validator to the aggregator
      const addValidator = inject(AddValidatorKey, () => {
        throw new Error("No aggregator provided for inject");
      });
      addValidator(validate);
      </script>
      

      【讨论】:

        【解决方案4】:

        您可以在子组件上使用 ref,然后在调用 someSubmitFunction 时尝试对该 ref 进行验证

        类似这样的:

          const isValid = await this.$refs.childref.validate()
        

        【讨论】:

          猜你喜欢
          • 2020-07-28
          • 2021-07-13
          • 2020-01-30
          • 1970-01-01
          • 2021-04-05
          • 2021-11-07
          • 2020-02-09
          • 1970-01-01
          • 2020-11-21
          相关资源
          最近更新 更多