Variable: FormWithValidation
ts
const FormWithValidation: DefineComponent<ExtractPropTypes<AppendDefault<{
additionalMessages: {
default: () => {
};
type: PropType<Record<string, string>>;
};
commonFieldOptions: {
default: () => {
};
type: PropType<Record<string, any>>;
};
debug: {
default: boolean;
type: BooleanConstructor;
};
fieldLabels: {
default: () => {
};
type: PropType<Record<string, string>>;
};
formInitialValues: {
required: true;
type: PropType<Record<string, any>>;
};
fullSchema: {
required: true;
type: JoiSchemaPropType<any>;
};
onPreventedSubmit?: PropType<
| (...args: [Record<string, any>, ValidationError]) => void
| undefined>;
onState:dirty?: PropType<(...args: [boolean]) => void | undefined>;
onState:errorBag?: PropType<
| (...args: [Partial<Record<..., ...>>]) => void
| undefined>;
onState:errors?: PropType<
| (...args: [Record<string, ... | ...>]) => void
| undefined>;
onState:pending?: PropType<(...args: [boolean]) => void | undefined>;
onState:submitCount?: PropType<(...args: [number]) => void | undefined>;
onState:submitting?: PropType<(...args: [boolean]) => void | undefined>;
onState:touched?: PropType<(...args: [boolean]) => void | undefined>;
onState:valid?: PropType<(...args: [boolean]) => void | undefined>;
onState:validating?: PropType<(...args: [boolean]) => void | undefined>;
onState:values?: PropType<
| (...args: [Record<string, any>]) => void
| undefined>;
options: {
default: () => {
};
type: PropType<AsyncValidationOptions>;
};
overrideMessages: {
default: () => {
};
type: PropType<Partial<Record<
| "alternatives.all"
| "alternatives.any"
| "alternatives.match"
| "alternatives.one"
| "alternatives.types"
| "any.custom"
| "any.default"
| "any.failover"
| "any.invalid"
| "any.only"
| "any.ref"
| "any.required"
| "any.unknown"
| "array.base"
| "array.excludes"
| "array.hasKnown"
| "array.hasUnknown"
| "array.includes"
| "array.includesRequiredBoth"
| "array.includesRequiredKnowns"
| "array.includesRequiredUnknowns"
| "array.length"
| "array.max"
| "array.min"
| "array.orderedLength"
| "array.sort"
| "array.sort.mismatching"
| "array.sort.unsupported"
| "array.sparse"
| "array.unique"
| "boolean.base"
| "date.base"
| "date.format"
| "date.greater"
| "date.less"
| "date.max"
| "date.min"
| "date.format.iso"
| "date.format.javascript"
| "date.format.unix"
| "function.arity"
| "function.class"
| "function.maxArity"
| "function.minArity"
| "number.base"
| "number.greater"
| "number.infinity"
| "number.integer"
| "number.less"
| "number.max"
| "number.min"
| "number.multiple"
| "number.negative"
| "number.port"
| "number.positive"
| "number.precision"
| "number.unsafe"
| "object.and"
| "object.assert"
| "object.base"
| "object.instance"
| "object.length"
| "object.max"
| "object.min"
| "object.missing"
| "object.nand"
| "object.oxor"
| "object.pattern.match"
| "object.refType"
| "object.regex"
| "object.rename.multiple"
| "object.rename.override"
| "object.schema"
| "object.unknown"
| "object.with"
| "object.without"
| "object.xor"
| "string.alphanum"
| "string.base"
| "string.base64"
| "string.creditCard"
| "string.dataUri"
| "string.domain"
| "string.email"
| "string.empty"
| "string.guid"
| "string.hex"
| "string.hexAlign"
| "string.hostname"
| "string.ip"
| "string.ipVersion"
| "string.isoDate"
| "string.isoDuration"
| "string.length"
| "string.lowercase"
| "string.max"
| "string.min"
| "string.normalize"
| "string.token"
| "string.pattern.base"
| "string.pattern.name"
| "string.pattern.invert.base"
| "string.pattern.invert.name"
| "string.trim"
| "string.uri"
| "string.uriCustomScheme"
| "string.uriRelativeOnly"
| "string.uppercase"
| "symbol.base"
| "symbol.map"
| "binary.base"
| "binary.length"
| "binary.max"
| "binary.min"
| "bigint.base"
| "bigint.greater"
| "bigint.less"
| "bigint.max"
| "bigint.min"
| "bigint.multiple"
| "bigint.negative"
| "bigint.positive"
| "datetime.base"
| "datetime.exactly"
| "datetime.equals"
| "datetime.after"
| "datetime.greater"
| "datetime.before"
| "datetime.less"
| "datetime.afterOrEqual"
| "datetime.min"
| "datetime.beforeOrEqual"
| "datetime.max"
| "datetime.weekend"
| "datetime.weekday"
| "phone.base"
| "phone.invalid"
| "phone.fixedLine"
| "phone.mobile"
| "phone.strictFixedLine"
| "phone.strictMobile"
| "phone.fixedLineOrMobile"
| "phone.tollFree"
| "phone.premiumRate"
| "phone.sharedCost"
| "phone.voip"
| "phone.personalNumber"
| "phone.pager"
| "phone.uan"
| "phone.voicemail"
| "phone.unknown"
| "phone.types", string>>>;
};
specificFieldOptions: {
default: () => {
};
type: PropType<Record<string, Record<string, any>>>;
};
submissionHandler: {
required: true;
type: PropType<(values: any) => MaybePromise<void>>;
};
}, {
}>>, {
formErrorBag: Ref<Partial<Record<string, string[]>>, Partial<Record<string, string[]>>>;
formErrors: ComputedRef<Partial<Record<string, string | undefined>>>;
formIsDirty: ComputedRef<boolean>;
formIsPending: ComputedRef<boolean>;
formIsSubmitting: Ref<boolean, boolean>;
formIsTouched: ComputedRef<boolean>;
formIsValid: ComputedRef<boolean>;
formIsValidating: Ref<boolean, boolean>;
formSubmitCount: Ref<number, number>;
formValues: any;
reset: () => void;
setFieldTouched: (field: string, isTouched: boolean) => void;
setFieldValue: (field: string, value: any) => void;
setTouched: (fields:
| boolean
| Partial<Record<string, boolean>>) => void;
setValues: (fields: any, shouldValidate?: boolean) => void;
submit: () => void;
validate: (opts?: Partial<ValidationOptions$1>) => Promise<FormValidationResult<any, any>>;
validateField: <TPath>(field: TPath, opts?: Partial<ValidationOptions$1>) => Promise<ValidationResult<any>>;
}, {
}, {
}, {
}, ComponentOptionsMixin, ComponentOptionsMixin, EmitFunctions<{
preventedSubmit: (values: Record<string, any>, error: ValidationError) => boolean;
state:dirty: (is: boolean) => boolean;
state:errorBag: (errors: Partial<Record<string, string[]>>) => boolean;
state:errors: (errors: Record<string, string | undefined>) => boolean;
state:pending: (is: boolean) => boolean;
state:submitCount: (count: number) => boolean;
state:submitting: (is: boolean) => boolean;
state:touched: (is: boolean) => boolean;
state:valid: (is: boolean) => boolean;
state:validating: (is: boolean) => boolean;
state:values: (values: Record<string, any>) => values is { [key: string]: unknown };
}>, string, PublicProps, ToResolvedProps<ExtractPropTypes<AppendDefault<{
additionalMessages: {
default: () => {
};
type: PropType<Record<string, string>>;
};
commonFieldOptions: {
default: () => {
};
type: PropType<Record<string, any>>;
};
debug: {
default: boolean;
type: BooleanConstructor;
};
fieldLabels: {
default: () => {
};
type: PropType<Record<string, string>>;
};
formInitialValues: {
required: true;
type: PropType<Record<string, any>>;
};
fullSchema: {
required: true;
type: JoiSchemaPropType<any>;
};
onPreventedSubmit?: PropType<
| (...args: [Record<..., ...>, ValidationError]) => void
| undefined>;
onState:dirty?: PropType<(...args: [boolean]) => void | undefined>;
onState:errorBag?: PropType<
| (...args: [Partial<...>]) => void
| undefined>;
onState:errors?: PropType<
| (...args: [Record<..., ...>]) => void
| undefined>;
onState:pending?: PropType<(...args: [boolean]) => void | undefined>;
onState:submitCount?: PropType<(...args: [number]) => void | undefined>;
onState:submitting?: PropType<(...args: [boolean]) => void | undefined>;
onState:touched?: PropType<(...args: [boolean]) => void | undefined>;
onState:valid?: PropType<(...args: [boolean]) => void | undefined>;
onState:validating?: PropType<(...args: [boolean]) => void | undefined>;
onState:values?: PropType<
| (...args: [Record<..., ...>]) => void
| undefined>;
options: {
default: () => {
};
type: PropType<AsyncValidationOptions>;
};
overrideMessages: {
default: () => {
};
type: PropType<Partial<Record<
| "alternatives.all"
| "alternatives.any"
| "alternatives.match"
| "alternatives.one"
| "alternatives.types"
| "any.custom"
| "any.default"
| "any.failover"
| "any.invalid"
| "any.only"
| "any.ref"
| "any.required"
| "any.unknown"
| "array.base"
| "array.excludes"
| "array.hasKnown"
| "array.hasUnknown"
| "array.includes"
| "array.includesRequiredBoth"
| "array.includesRequiredKnowns"
| "array.includesRequiredUnknowns"
| "array.length"
| "array.max"
| "array.min"
| "array.orderedLength"
| "array.sort"
| "array.sort.mismatching"
| "array.sort.unsupported"
| "array.sparse"
| "array.unique"
| "boolean.base"
| "date.base"
| "date.format"
| "date.greater"
| "date.less"
| "date.max"
| "date.min"
| "date.format.iso"
| "date.format.javascript"
| "date.format.unix"
| "function.arity"
| "function.class"
| "function.maxArity"
| "function.minArity"
| "number.base"
| "number.greater"
| "number.infinity"
| "number.integer"
| "number.less"
| "number.max"
| "number.min"
| "number.multiple"
| "number.negative"
| "number.port"
| "number.positive"
| "number.precision"
| "number.unsafe"
| "object.and"
| "object.assert"
| "object.base"
| "object.instance"
| "object.length"
| "object.max"
| "object.min"
| "object.missing"
| "object.nand"
| "object.oxor"
| "object.pattern.match"
| "object.refType"
| "object.regex"
| "object.rename.multiple"
| "object.rename.override"
| "object.schema"
| "object.unknown"
| "object.with"
| "object.without"
| "object.xor"
| "string.alphanum"
| "string.base"
| "string.base64"
| "string.creditCard"
| "string.dataUri"
| "string.domain"
| "string.email"
| "string.empty"
| "string.guid"
| "string.hex"
| "string.hexAlign"
| "string.hostname"
| "string.ip"
| "string.ipVersion"
| "string.isoDate"
| "string.isoDuration"
| "string.length"
| "string.lowercase"
| "string.max"
| "string.min"
| "string.normalize"
| "string.token"
| "string.pattern.base"
| "string.pattern.name"
| "string.pattern.invert.base"
| "string.pattern.invert.name"
| "string.trim"
| "string.uri"
| "string.uriCustomScheme"
| "string.uriRelativeOnly"
| "string.uppercase"
| "symbol.base"
| "symbol.map"
| "binary.base"
| "binary.length"
| "binary.max"
| "binary.min"
| "bigint.base"
| "bigint.greater"
| "bigint.less"
| "bigint.max"
| "bigint.min"
| "bigint.multiple"
| "bigint.negative"
| "bigint.positive"
| "datetime.base"
| "datetime.exactly"
| "datetime.equals"
| "datetime.after"
| "datetime.greater"
| "datetime.before"
| "datetime.less"
| "datetime.afterOrEqual"
| "datetime.min"
| "datetime.beforeOrEqual"
| "datetime.max"
| "datetime.weekend"
| "datetime.weekday"
| "phone.base"
| "phone.invalid"
| "phone.fixedLine"
| "phone.mobile"
| "phone.strictFixedLine"
| "phone.strictMobile"
| "phone.fixedLineOrMobile"
| "phone.tollFree"
| "phone.premiumRate"
| "phone.sharedCost"
| "phone.voip"
| "phone.personalNumber"
| "phone.pager"
| "phone.uan"
| "phone.voicemail"
| "phone.unknown"
| "phone.types", string>>>;
};
specificFieldOptions: {
default: () => {
};
type: PropType<Record<string, Record<string, any>>>;
};
submissionHandler: {
required: true;
type: PropType<(values: any) => MaybePromise<void>>;
};
}, {
}>>, EmitFunctions<{
preventedSubmit: (values: Record<string, any>, error: ValidationError) => boolean;
state:dirty: (is: boolean) => boolean;
state:errorBag: (errors: Partial<Record<string, string[]>>) => boolean;
state:errors: (errors: Record<string, string | undefined>) => boolean;
state:pending: (is: boolean) => boolean;
state:submitCount: (count: number) => boolean;
state:submitting: (is: boolean) => boolean;
state:touched: (is: boolean) => boolean;
state:valid: (is: boolean) => boolean;
state:validating: (is: boolean) => boolean;
state:values: (values: Record<string, any>) => values is { [key: string]: unknown };
}>>, {
additionalMessages: Record<string, string>;
commonFieldOptions: Record<string, any>;
debug: boolean;
fieldLabels: Record<string, string>;
options: AsyncValidationOptions;
overrideMessages: Partial<Record<
| "alternatives.all"
| "alternatives.any"
| "alternatives.match"
| "alternatives.one"
| "alternatives.types"
| "any.custom"
| "any.default"
| "any.failover"
| "any.invalid"
| "any.only"
| "any.ref"
| "any.required"
| "any.unknown"
| "array.base"
| "array.excludes"
| "array.hasKnown"
| "array.hasUnknown"
| "array.includes"
| "array.includesRequiredBoth"
| "array.includesRequiredKnowns"
| "array.includesRequiredUnknowns"
| "array.length"
| "array.max"
| "array.min"
| "array.orderedLength"
| "array.sort"
| "array.sort.mismatching"
| "array.sort.unsupported"
| "array.sparse"
| "array.unique"
| "boolean.base"
| "date.base"
| "date.format"
| "date.greater"
| "date.less"
| "date.max"
| "date.min"
| "date.format.iso"
| "date.format.javascript"
| "date.format.unix"
| "function.arity"
| "function.class"
| "function.maxArity"
| "function.minArity"
| "number.base"
| "number.greater"
| "number.infinity"
| "number.integer"
| "number.less"
| "number.max"
| "number.min"
| "number.multiple"
| "number.negative"
| "number.port"
| "number.positive"
| "number.precision"
| "number.unsafe"
| "object.and"
| "object.assert"
| "object.base"
| "object.instance"
| "object.length"
| "object.max"
| "object.min"
| "object.missing"
| "object.nand"
| "object.oxor"
| "object.pattern.match"
| "object.refType"
| "object.regex"
| "object.rename.multiple"
| "object.rename.override"
| "object.schema"
| "object.unknown"
| "object.with"
| "object.without"
| "object.xor"
| "string.alphanum"
| "string.base"
| "string.base64"
| "string.creditCard"
| "string.dataUri"
| "string.domain"
| "string.email"
| "string.empty"
| "string.guid"
| "string.hex"
| "string.hexAlign"
| "string.hostname"
| "string.ip"
| "string.ipVersion"
| "string.isoDate"
| "string.isoDuration"
| "string.length"
| "string.lowercase"
| "string.max"
| "string.min"
| "string.normalize"
| "string.token"
| "string.pattern.base"
| "string.pattern.name"
| "string.pattern.invert.base"
| "string.pattern.invert.name"
| "string.trim"
| "string.uri"
| "string.uriCustomScheme"
| "string.uriRelativeOnly"
| "string.uppercase"
| "symbol.base"
| "symbol.map"
| "binary.base"
| "binary.length"
| "binary.max"
| "binary.min"
| "bigint.base"
| "bigint.greater"
| "bigint.less"
| "bigint.max"
| "bigint.min"
| "bigint.multiple"
| "bigint.negative"
| "bigint.positive"
| "datetime.base"
| "datetime.exactly"
| "datetime.equals"
| "datetime.after"
| "datetime.greater"
| "datetime.before"
| "datetime.less"
| "datetime.afterOrEqual"
| "datetime.min"
| "datetime.beforeOrEqual"
| "datetime.max"
| "datetime.weekend"
| "datetime.weekday"
| "phone.base"
| "phone.invalid"
| "phone.fixedLine"
| "phone.mobile"
| "phone.strictFixedLine"
| "phone.strictMobile"
| "phone.fixedLineOrMobile"
| "phone.tollFree"
| "phone.premiumRate"
| "phone.sharedCost"
| "phone.voip"
| "phone.personalNumber"
| "phone.pager"
| "phone.uan"
| "phone.voicemail"
| "phone.unknown"
| "phone.types", string>>;
specificFieldOptions: Record<string, Record<string, any>>;
}, FormWithValidationSlots, {
}, {
}, string, ComponentProvideOptions, true, {
}, any>;Enterprise-grade form validation component that provides a complete form wrapper with validation state management, field binding generation, and event emission.
This component wraps the useValidation composable in a reusable component interface, providing automatic form element generation, state emission to parent components, and scoped display utilities for responsive form layouts.
Example
vue
<template>
<FormWithValidation
:full-schema="userSchema"
:form-initial-values="{ name: '', email: '' }"
:submission-handler="handleSubmit"
@state:valid="onValidationChange"
>
<template #default="{ formFieldBindings, useField, formIsValid }">
<VTextField v-bind="formFieldBindings.name" label="Name" />
<VTextField v-bind="formFieldBindings.email" label="Email" />
<!-- Nested field example -->
<VTextField v-bind="useField('profile.bio')" label="Bio" />
<VBtn :disabled="!formIsValid" type="submit"> Submit </VBtn>
</template>
</FormWithValidation>
</template>