Skip to content

Function: useValidation() ​

ts
function useValidation<TSchema>(
  fullSchema: MaybeRef<TSchema>,
  formInitialValues: MaybeRef<Record<string, any>>,
  onSubmit: (values: DataTypeOf<TSchema>) => MaybePromise<void>,
  additional: MaybeRef<Record<string, string>>,
  overrides: MaybeRef<
    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
      >
    >
  >,
  options: MaybeRef<AsyncValidationOptions>,
  name: string,
  debug: MaybeRef<boolean>,
  onPreventedSubmit: (
    values: DataTypeOf<TSchema>,
    error: ValidationError,
  ) => MaybePromise<void>,
  fieldLabels: MaybeRef<Record<string, string>>,
  commonFieldOptions: MaybeRef<Record<string, any>>,
  specificFieldOptions: MaybeRef<Record<string, Record<string, any>>>,
): {
  doFormSubmit: (e?: Event) => Promise<MaybePromise<void> | undefined>;
  doResetForm: (
    state?: Partial<FormState<any>>,
    opts?: Partial<ResetFormOpts>,
  ) => void;
  forceUpdateInitialValues: () => void;
  forceUpdateSchema: () => void;
  formBindings: ComputedRef<FormHTMLAttributes>;
  formErrorBag: Ref<
    Partial<Record<string, string[]>>,
    Partial<Record<string, string[]>>
  >;
  formErrors: ComputedRef<Partial<Record<string, string | undefined>>>;
  formFieldBindings: ComputedRef<Record<string, ValidationFieldBindings<any>>>;
  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;
  setErrors: (
    fields: Partial<
      FlattenAndSetPathsType<TValues, string | string[] | undefined>
    >,
  ) => 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;
  useField: (
    path: string,
    options?: {
      validateOnBlur?: boolean;
      validateOnChange?: boolean;
      validateOnInput?: boolean;
      validateOnModelUpdate?: boolean;
    },
  ) => ComputedRef<ValidationFieldBindings<any>>;
  validate: (
    opts?: Partial<ValidationOptions$1>,
  ) => Promise<FormValidationResult<any, any>>;
  validateField: <TPath>(
    field: TPath,
    opts?: Partial<ValidationOptions$1>,
  ) => Promise<ValidationResult<any>>;
  validationSchema: ShallowRef<ObjectSchema<any>, ObjectSchema<any>>;
};

Enterprise-grade form validation composable that bridges Joi schemas with VeeValidate and Vuetify. Provides comprehensive form state management, validation, and field binding generation.

Type Parameters ​

Type ParameterDescription
TSchema extends SchemaThe Joi schema type

Parameters ​

ParameterTypeDefault valueDescription
fullSchemaMaybeRef<TSchema>undefinedJoi schema defining validation rules for the entire form
formInitialValuesMaybeRef<Record<string, any>>undefinedInitial values for form fields (determines which fields are active)
onSubmit(values: DataTypeOf<TSchema>) => MaybePromise<void>undefinedForm submission handler receiving validated form values
additionalMaybeRef<Record<string, string>>{}Additional custom validation messages not in standard Joi set
overridesMaybeRef<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>>>{}Override standard Joi validation messages with custom ones
optionsMaybeRef<AsyncValidationOptions>{}Joi validation options (async validation settings)
namestring...Form instance name for debugging and component identification
debugMaybeRef<boolean>falseEnable debug logging for validation failures
onPreventedSubmit(values: DataTypeOf<TSchema>, error: ValidationError) => MaybePromise<void>...-
fieldLabelsMaybeRef<Record<string, string>>{}-
commonFieldOptionsMaybeRef<Record<string, any>>{}-
specificFieldOptionsMaybeRef<Record<string, Record<string, any>>>{}-

Returns ​

ts
{
  doFormSubmit: (e?: Event) => Promise<
     | MaybePromise<void>
    | undefined>;
  doResetForm: (state?: Partial<FormState<any>>, opts?: Partial<ResetFormOpts>) => void;
  forceUpdateInitialValues: () => void;
  forceUpdateSchema: () => void;
  formBindings: ComputedRef<FormHTMLAttributes>;
  formErrorBag: Ref<Partial<Record<string, string[]>>, Partial<Record<string, string[]>>>;
  formErrors: ComputedRef<Partial<Record<string, string | undefined>>>;
  formFieldBindings: ComputedRef<Record<string, ValidationFieldBindings<any>>>;
  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;
  setErrors: (fields: Partial<FlattenAndSetPathsType<TValues, string | string[] | undefined>>) => 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;
  useField: (path: string, options?: {
     validateOnBlur?: boolean;
     validateOnChange?: boolean;
     validateOnInput?: boolean;
     validateOnModelUpdate?: boolean;
  }) => ComputedRef<ValidationFieldBindings<any>>;
  validate: (opts?: Partial<ValidationOptions$1>) => Promise<FormValidationResult<any, any>>;
  validateField: <TPath>(field: TPath, opts?: Partial<ValidationOptions$1>) => Promise<ValidationResult<any>>;
  validationSchema: ShallowRef<ObjectSchema<any>, ObjectSchema<any>>;
}

Object containing form state, field bindings, validation methods, and nested field helper

NameTypeDefault value
doFormSubmit()(e?: Event) => Promise< | MaybePromise<void> | undefined>-
doResetForm()(state?: Partial<FormState<any>>, opts?: Partial<ResetFormOpts>) => voidresetForm
forceUpdateInitialValues()() => voidupdateInitialValues
forceUpdateSchema()() => void-
formBindingsComputedRef<FormHTMLAttributes>-
formErrorBagRef<Partial<Record<string, string[]>>, Partial<Record<string, string[]>>>errorBag
formErrorsComputedRef<Partial<Record<string, string | undefined>>>errors
formFieldBindingsComputedRef<Record<string, ValidationFieldBindings<any>>>fieldBindings
formIsDirtyComputedRef<boolean>-
formIsPendingComputedRef<boolean>-
formIsSubmittingRef<boolean, boolean>isSubmitting
formIsTouchedComputedRef<boolean>-
formIsValidComputedRef<boolean>-
formIsValidatingRef<boolean, boolean>isValidating
formSubmitCountRef<number, number>submitCount
formValuesany-
setErrors()(fields: Partial<FlattenAndSetPathsType<TValues, string | string[] | undefined>>) => 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-
useField()(path: string, options?: { validateOnBlur?: boolean; validateOnChange?: boolean; validateOnInput?: boolean; validateOnModelUpdate?: boolean; }) => ComputedRef<ValidationFieldBindings<any>>-
validate()(opts?: Partial<ValidationOptions$1>) => Promise<FormValidationResult<any, any>>-
validateField()<TPath>(field: TPath, opts?: Partial<ValidationOptions$1>) => Promise<ValidationResult<any>>-
validationSchemaShallowRef<ObjectSchema<any>, ObjectSchema<any>>formSchema

Example ​

typescript
const schema = joi.object({
  name: joi.string().required(),
  email: joi.string().email().required(),
  settings: joi.object({
    theme: joi.string().valid("light", "dark"),
  }),
});

const { formFieldBindings, useField, formIsValid, doFormSubmit } =
  useValidation(
    schema,
    { name: "", email: "", settings: { theme: "light" } },
    async (values) => {
      await api.saveUser(values);
    },
  );

// Use flat bindings
const nameField = formFieldBindings.name;

// Use nested fields
const themeField = useField("settings.theme");