Last active
January 15, 2025 17:46
-
-
Save sohseyedi-web/18b2add362ec95173c2a3eb59816edf0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //types | |
| import type { Ref } from "vue"; | |
| import type { z, ZodTypeAny } from "zod"; | |
| export type ZodFormType<T extends ZodTypeAny> = z.infer<T>; | |
| export interface ValidateFormType<T extends ZodTypeAny> { | |
| values: ZodFormType<T>; | |
| schema: T; | |
| errors: Ref<Record<string, string>>; | |
| field?: keyof ZodFormType<T>; | |
| } | |
| //utils | |
| import type { ValidateFormType, ZodFormType } from '@/types' | |
| import type { ZodTypeAny } from 'zod' | |
| export function validateForm<T extends ZodTypeAny>({ values, schema, errors }: ValidateFormType<T>): boolean { | |
| const res = schema.safeParse(values) | |
| if (res.success) { | |
| errors.value = {} | |
| return true | |
| } | |
| else { | |
| const formErrors: Record<string, string> = {} | |
| for (const [key, val] of Object.entries(res.error.formErrors.fieldErrors)) { | |
| formErrors[key] = Array.isArray(val) ? val[0] : val || '' | |
| } | |
| errors.value = formErrors | |
| return false | |
| } | |
| } | |
| export function validateField<T extends ZodTypeAny>({ values, schema, errors, field }: ValidateFormType<T>) { | |
| try { | |
| const res = schema.safeParse(values) as ZodFormType<T> | |
| const error = res.success ? '' : res.error.formErrors.fieldErrors[field] | |
| errors.value[field as string] = Array.isArray(error) ? error[0] : error || '' | |
| } | |
| catch { | |
| } | |
| } | |
| //useValid | |
| import type { ZodTypeAny } from 'zod' | |
| import { validateField, validateForm } from '@/utils' | |
| import { ref, watch } from 'vue' | |
| import { z } from 'zod' | |
| function useValid<T extends ZodTypeAny>(initialValues: unknown,schema: T) { | |
| type ZodForm = z.infer<T> | |
| const values = ref<ZodForm>(initialValues) | |
| const errors = ref<Record<string, string>>({}) | |
| const isValidForm = ref<boolean>(false) | |
| const runValidation = () => { | |
| isValidForm.value = validateForm({ values: values.value, schema, errors }) | |
| } | |
| watch( | |
| values, | |
| (newValues: ZodForm) => { | |
| for (const fieldName of Object.keys(newValues)) { | |
| validateField({ values: values.value, schema, errors, field: fieldName }) | |
| } | |
| runValidation() | |
| }, | |
| { deep: true }, | |
| ) | |
| runValidation() | |
| return { | |
| values, | |
| errors, | |
| isValidForm, | |
| validateField, | |
| } | |
| } | |
| //schema | |
| export const exampleSchema = z.object({ | |
| text: z | |
| .string() | |
| .min(1, 'Error') | |
| }) | |
| // code | |
| const { errors, validateForm, values } = useValid({ text: '' }, exampleSchema) | |
| function onSubmit() { | |
| console.log(values.value) | |
| } | |
| <input | |
| v-model="values.text" | |
| type="text" | |
| placeholder="..." | |
| name="text" | |
| /> | |
| <span>{{errors.text}}</span> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment