使用 Zod 进行表单校验

官网:Intro | Zod
Zod 是一个现代化、强大的,用于表单校验的库,其设计能很好的支持服务端渲染等现代化的未来场景,同时更是广泛支持各种框架和组件库,他被 NextJS 官方推荐使用。
我认为 zod 的两个最大优点:
- 不止是运行时的数据校验,也提供开发时的类型安全(请见本文下面的:[[#3. 推断类型]])
- 一次声明,处处验证。定义好一次后,可以给客户端的 React Hook Form 使用,也可以给服务端做校验,成为唯一真相来源,根本解决了同步问题。
使用
1. 定义蓝图
schema 这个词有结构或者蓝图的意思,我们定义好一个数据的 schema,其实就是说明它应该“长什么样”。
Zod 的核心是一个 z 对象,它提供了创建各种数据类型 schema 的方法。
1 | import { z } from 'zod'; |
是不是非常直观?z.string() 就创建了一个期望数据是字符串的 schema。
schema 里应该定义些什么?
不同于数据库里的数据结构,这里 schema 定义的类型只关注用户输入的那部分。
事实上,下面三种数据结构不同,也应该做区分:
- 存在数据库里的数据,可能包括每个条目的 UUID 等。
- 展示给用户看的数据,比如 Todo List 的完成/未完成这个布尔值,这个是隐式的。
- 用户填的数据,比如 Todo List 里用户真正定义的可能只有 content 。(这才是 Zod 所需要定义的)
schema 的代码应该放在哪里?
我推荐使用现代前端社区推荐的 ducks 风格,这是一种高内聚、低耦合的组织代码的方式,他利用“切片,slice” 的概念,把同一部分逻辑全部放在一起。
例如在 todo list 案例中,我决定在 src\features\todos\schema.ts
里创建一个定义新增 todo 表单类型的 schema 文件:
1 | import z from "zod"; |
如果是全局都能用到的 schema,在 src\schema
里创建 todos.ts
也许会是更好的选择。
2. 通过安检门
Zod 提供了两个主要的方法:.parse() 和 .safeParse()。
这两个方法的返回值,是经过校验的、可以真正传给后端或者使用的东西,因为经过这一道门,我们总能确信数据是正确的了, 就像一个安检门一样。
.parse(data)
这个方法会验证 data 是否符合 schema。如果符合,它会返回被验证过的数据;如果不符合,它会直接抛出一个错误。
1 | const nameSchema = z.string(); |
.parse() 适合用在那些你非常确定数据格式,或者希望在格式错误时直接中断程序流程的场景。
.safeParse(data) 🌟
这个是最常用的方法,它极其适合配合 UI 优雅的处理用户输入合法性校验问题。
-
如果验证成功,返回 { success: true, data: validatedData }。
-
如果验证失败,返回 { success: false, error: ZodError }。
1 | const emailSchema = z.string().email(); // Zod 内置了 email 格式校验 |
由于即使是成功,返回的也是一个对象,所以我们需要额外注意使用 result.data
来读到实际的数据。
- 链式 API: Zod 提供了丰富且可链式调用的 API(.min, .optional, .email 等),让 schema 定义既简洁又强大。
比如可以像这样连着调用:这定义一个由该 schema 元素组成的数组。1
const tagsSchema = z.string().array().min(1, "至少需要一个标签");
- 组合与扩展: 通过 .object, .array, .union, .extend 等方法,可以构建出任意复杂的数据结构。
3. 推断类型
这是一个大有益于 IDE 类型推断,以此提升开发体验的,有关于 typescript 的事情。
核心是 z.infer<typeof yourSchema>
方法,其中的 yourSchema 就是你在第一步中定义的 schema 。
这个方法产出的类型,可以在之后的开发中使用。
1 | import { z } from 'zod'; |
4. 结合使用
你可以在这里看到 zod 的生态:
最常见的是结合 React Hook Form 使用:
1 | pnpm install @hookform/resolvers zod |
- 标题: 使用 Zod 进行表单校验
- 作者: 三葉Leaves
- 创建于 : 2025-09-05 00:00:00
- 更新于 : 2025-09-05 11:19:12
- 链接: https://blog.oksanye.com/9e7b775c2e0c/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。