嵌套Zod Schema的表单验证失效问题求助
表单嵌套对象验证失效问题
我遇到一个表单问题:将地址字段分组到formData和Zod Schema的嵌套对象中时,表单无法正常工作;但使用平铺字段结构时却能正常运行。以下是两种结构的代码示例、模板代码,想请教问题出在哪里?
可正常工作的代码
formData
const formData = ref({ email: "", firstName: "", lastName: "", street: "", addressDetails: "", // 其他字段... });
Zod Schema
const schema = z.object({ email: z .string() .min(1, { message: "邮箱不能为空" }) .email("无效的邮箱格式"), firstName: z.string().min(1, { message: "名字不能为空" }), lastName: z.string().min(1, { message: "姓氏不能为空" }), // 其他字段验证规则... });
无法正常工作的代码
formData
const formData = ref({ email: "", address: { firstName: "", lastName: "", // 其他地址字段... } });
Zod Schema
const schema = z.object({ email: z .string() .min(1, { message: "邮箱不能为空" }) .email("无效的邮箱格式"), address: z.object({ firstName: z.string().min(1, { message: "名字不能为空" }), lastName: z.string().min(1, { message: "姓氏不能为空" }), // 其他地址字段验证规则... }), });
模板代码
<UForm :state="formData" :schema="schema" @submit="onSubmit" > <checkoutAccount v-model="formData.email" /> <formsAddress v-model:firstName="formData.address.firstName" v-model:lastName="formData.address.lastName" v-model:street="formData.address.street" v-model:addressDetails="formData.address.addressDetails" v-model:city="formData.address.city" v-model:postalcode="formData.address.postalcode" v-model:country="formData.address.country" /> </UForm>
问题原因与解决方法
核心问题在于Nuxt UI的UForm组件对嵌套对象的响应式追踪和验证路径处理逻辑:
- 当使用多props的v-model绑定嵌套字段时,
UForm无法自动识别嵌套对象内部的字段变化,导致验证逻辑未触发。 - Zod的嵌套验证规则需要组件正确识别
address.firstName这类完整字段路径,而当前的绑定方式没有传递完整路径信息。
可行解决思路
统一子组件的v-model绑定为完整嵌套对象
将formsAddress组件修改为接收整个address对象作为v-model,而非拆分多个单独props:<formsAddress v-model="formData.address" />组件内部通过
modelValueprops接收地址对象,更新时通过$emit('update:modelValue', newAddressObject)触发响应式更新,让UForm能直接追踪嵌套对象的变化。手动触发验证更新
如果必须保留多props绑定,可在子组件每个字段更新时,通过ref获取UForm实例并调用validate()方法,强制触发嵌套字段的验证逻辑。校验Schema字段一致性
确保Zod的嵌套address对象中,所有字段名与formData.address中的字段完全一致,避免拼写或遗漏导致验证不匹配。
内容的提问来源于stack exchange,提问作者Gregor
相关产品推荐
相关产品推荐

