如何在父子关系中使用 vee-validate
How to use vee-validate in a parent-child relationship
我有几个组件需要验证。问题是输入在子组件中,而提交按钮在父组件中,就像这样
ParentComponent.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>
我做错了什么?
您可以在子组件上使用 ref,然后在调用 someSubmitFunction
时尝试对该 ref 进行验证
像这样:
const isValid = await this.$refs.childref.validate()
幸运的是,有一种模式可以在父组件和子组件之间共享验证器范围!您可以 inject
验证器从父级到子级,以便它们使用相同的实例。这意味着您可以使用 this.$validator.validate()
验证来自父项的子项输入
文档:
http://vee-validate.logaretm.com/v2/concepts/injections.html
您可以像这样在创建的钩子中通过父组件验证器覆盖 chid 组件验证器的实例。
created() {
this.$validator = this.$parent.$validator
}
注意:如果你使用 mounted 它会起作用,因为在 DOM 渲染替换之前必须完成。
像我这样的人,以后和v4的vee-validate一起来这里求教 Vue3 Composition API and Typescript,我想推荐这个答案。它的工作原理是将 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>
当 运行 验证父 ValidationObserver 时,它也会验证子 ValidationObserver。
如果您只需要验证父 ValidationObserver,您可以为子观察者使用“禁用”道具。
https://vee-validate.logaretm.com/v3/api/validation-observer.html#props
<ValidationObserver ref="parent">
<ValidationObserver ref="child" :disabled="true">
<ValidationProvider rules="required">
<!-- This child observer will not be validated with parent validation -->
</ValidationProvider>
</ValidationObserver>
</ValidationObserver>
我有几个组件需要验证。问题是输入在子组件中,而提交按钮在父组件中,就像这样
ParentComponent.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>
我做错了什么?
您可以在子组件上使用 ref,然后在调用 someSubmitFunction
像这样:
const isValid = await this.$refs.childref.validate()
幸运的是,有一种模式可以在父组件和子组件之间共享验证器范围!您可以 inject
验证器从父级到子级,以便它们使用相同的实例。这意味着您可以使用 this.$validator.validate()
文档: http://vee-validate.logaretm.com/v2/concepts/injections.html
您可以像这样在创建的钩子中通过父组件验证器覆盖 chid 组件验证器的实例。
created() {
this.$validator = this.$parent.$validator
}
注意:如果你使用 mounted 它会起作用,因为在 DOM 渲染替换之前必须完成。
像我这样的人,以后和v4的vee-validate一起来这里求教 Vue3 Composition API and Typescript,我想推荐这个答案。它的工作原理是将 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>
当 运行 验证父 ValidationObserver 时,它也会验证子 ValidationObserver。
如果您只需要验证父 ValidationObserver,您可以为子观察者使用“禁用”道具。
https://vee-validate.logaretm.com/v3/api/validation-observer.html#props
<ValidationObserver ref="parent">
<ValidationObserver ref="child" :disabled="true">
<ValidationProvider rules="required">
<!-- This child observer will not be validated with parent validation -->
</ValidationProvider>
</ValidationObserver>
</ValidationObserver>