【免费下载链接】formisch
The lightweight, schema-first, and fully type-safe form library for React, Solid, Vue, Svelte and more.
Formisch 是一款轻量级、Schema 优先、完全类型安全的 React 表单库。它基于 Valibot 做表单验证,把表单状态管理与校验规则合二为一,包体积仅约 2.5 kB 起步。本文带你用 5 分钟,在 React 中用 Valibot 模式打造第一个类型安全的登录表单——定义 Schema、连接输入框、处理提交,全程零手动类型声明,编辑器自动补全字段路径。
Formisch 表单库简介:轻量、快速、类型安全
在动手之前,先了解 Formisch 的核心优势,这也是它区别于传统 React 表单库的关键:
- 小包体积:模块化设计,按需引入,起始约 2.5 kB
- Schema 验证:基于 Valibot,一份 Schema 同时承担结构与验证规则
- 端到端类型安全:字段路径、输入值、错误信息全链路类型推断,编辑器内自动补全
- 细粒度更新:只更新必要的 DOM,避免整表单重渲染
- 无头设计(Headless):不绑定任何 UI 组件,样式与组件库自由组合
- 多框架支持:同一套心智模型覆盖 React、Vue、Svelte、Solid、Preact、Qwik、Angular 等
下图是 Formisch 官方文档中登录表单的示例代码,useForm、<Form />与<Field />三者组合就是整篇文章的主角:
一键安装步骤:安装 Formisch 与 Valibot 依赖
Formisch 使用 Valibot 作为验证引擎,Valibot 是它的 peer dependency,需要先装 Valibot,再装 Formisch。在终端执行:
# 1. 先安装 Valibot 验证库 npm install valibot # 2. 再安装 Formisch 的 React 包 npm install @formisch/react💡Tip:如果使用 TypeScript,建议在
tsconfig.json中开启strict模式(要求 TypeScript ≥ 5.0.2),这样 Schema 的类型推断才能完整生效。
安装完成后即可在任意文件中导入:
import { Form, Field, useForm } from '@formisch/react';详细的安装说明可参考官方文档 installation/index.mdx/react/guides/(get-started)/installation/index.mdx)。
第一步:用 Valibot Schema 定义登录表单结构
Formisch 是schema-first(模式优先)的表单库:不写 TypeScript 类型,而是写 Valibot Schema,类型会由 Schema 自动推导出来。
一个登录表单通常只有两个字段:邮箱和密码。用v.object定义结构,用v.pipe串联校验规则,并附上清晰的错误提示:
import * as v from 'valibot'; const LoginSchema = v.object({ email: v.pipe( v.string(), v.nonEmpty('Please enter your email.'), v.email('The email address is badly formatted.') ), password: v.pipe( v.string(), v.nonEmpty('Please enter your password.'), v.minLength(8, 'Your password must have 8 characters or more.') ), });Valibot Schema 类型推断:错误信息获得精确类型/react-form-library-comparison/type-safe-issues.jpg)
上图展示了 Valibot 的类型能力:连错误信息本身都会被推断为精确的联合类型(如v.StringIssue | v.MinLengthIssue<string, 1>),这就是 Formisch 类型安全的底层来源。
两个使用要点:
- 字段顺序即页面顺序:提交失败时 Formisch 会自动聚焦第一个出错的字段,所以 Schema 中的字段顺序请与页面布局保持一致。
- Schema 决定可提交的数据:可选项记得用
v.optional(…)声明,表单只有在完全匹配 Schema 时才能提交。
更多 Schema 写法可查阅官方指南 define-your-form/index.mdx/react/guides/(main-concepts)/define-your-form/index.mdx)。
第二步:用 useForm 钩子初始化 React 表单
Schema 定义好后,用useForm钩子在组件中初始化表单实例。它会根据 Schema 创建表单状态仓库(form store),类型自动推断,无需任何手动声明:
import { Field, Form, useForm } from '@formisch/react'; export default function LoginPage() { const loginForm = useForm({ schema: LoginSchema, }); return ( <Form of={loginForm} onSubmit={(output) => console.log(output)}> {/* 表单字段写在这里 */} </Form> ); }useForm接受以下常用配置项:
| 配置项 | 说明 |
|---|---|
schema | 你的 Valibot Schema,表单的蓝图 |
initialInput | 字段初始值(可选) |
emptyInput | 必填字段无初始值时的空值,默认为{ string: '' } |
validate | 何时首次校验,默认'submit' |
revalidate | 首次校验后何时重新校验,默认'input' |
Formisch 会为每个字段同时追踪初始值与当前值:当两者不一致时isDirty变为true,这让"是否有未保存修改"这类判断变得非常自然。
该钩子的实现位于 useForm.ts,配置选项详见 create-your-form/index.mdx/react/guides/(main-concepts)/create-your-form/index.mdx)。
第三步:用 Form 和 Field 组件连接输入框
<Form />是原生<form>元素的薄封装,负责验证与提交;<Field />是无头组件,通过of(表单实例)和path(字段路径)连接到 Schema 中的某个字段,并在 children 函数中把字段状态交给你:
import { Field, Form, useForm } from '@formisch/react'; export default function LoginPage() { const loginForm = useForm({ schema: LoginSchema }); return ( <Form of={loginForm} onSubmit={(output) => console.log(output)}> <Field of={loginForm} path={['email']}> {(field) => ( <div> <input {...field.props} value={field.input} type="email" /> {field.errors && <div>{field.errors[0]}</div>} </div> )} </Field> <Field of={loginForm} path={['password']}> {(field) => ( <div> <input {...field.props} value={field.input} type="password" /> {field.errors && <div>{field.errors[0]}</div>} </div> )} </Field> <button type="submit">Login</button> </Form> ); }字段状态对象(field store)包含这些常用属性:
field.input:当前输入值,类型由 Schema 推断field.errors:当前错误信息数组,可直接渲染field.props:展开到<input>上的事件处理器与属性(含name、ref,出错字段还会自动autoFocus)field.isTouched/field.isEdited/field.isDirty/field.isValid:交互与脏值状态
如果你拆出独立的字段组件,可以改用useField钩子直接获取字段状态,实现位于 useField.ts;<Field />本质上是它的薄封装(Field.tsx)。
⚠️ 注意:
field.props中的事件处理器从 DOM 读取的值是字符串。对v.number()、v.date()这类非字符串字段,需要受控写法(手动绑定value等属性)来保证类型正确。
第四步:处理表单提交与加载状态
最后一步:处理提交。给<Form />传入onSubmit函数,第一个参数就是通过验证的表单值——类型与 Schema 输出一一对应:
const submitForm: SubmitHandler<typeof LoginSchema> = async (values) => { const response = await fetch('/api/login', { method: 'POST', headers: { 'Content': 'application/json' }, body: JSON.stringify(values), // { email: string, password: string } }); if (response.ok) console.log('登录成功!'); };提交期间还可以用loginForm.isSubmitting显示加载态:
<button type="submit" disabled={loginForm.isSubmitting}> {loginForm.isSubmitting ? 'Submitting...' : 'Login'} </button>表单仓库还提供isSubmitted、isValidating、isTouched、isDirty、isValid等响应式状态。提交细节(含不包裹<Form />时用handleSubmit的场景)见 handle-submission/index.mdx/react/guides/(main-concepts)/handle-submission/index.mdx)。
常见问题与扩展学习路径
Q:为什么必须先安装 Valibot?A:Valibot 是 Formisch 的 peer dependency,负责 Schema 定义与验证执行,Formisch 核心只管理状态。
Q:嵌套字段怎么连接?A:path接受字符串数组,如path={['user', 'email']}对应v.object({ user: v.object({ email: v.string() }) }),嵌套路径同样是类型安全的。
Q:如何给复杂表单编程式控制字段?A:Formisch 提供一套方法 API,如setInput、reset、validate、getErrors、isDirty、submit等,按需导入即可。
想继续深入,推荐这几个仓库内的学习路径:
- 官方文档:docs react 目录/react)
- React Playground(含登录、嵌套、字段数组等完整示例):playgrounds/react/
- 真实业务示例(Svelte 发票表单,含金额/数量转换与字段数组):schema.ts
- React 框架包源码:frameworks/react/src/
- 核心包(框架无关的状态管理):packages/core/src/
至此,你已经用 5 分钟跑通了 Formisch + Valibot 的核心工作流:Schema 定义 → useForm 初始化 → Field 连接 → onSubmit 提交。以后新增字段只需改 Schema,类型、验证、错误提示全部自动跟上——这正是 Schema 优先表单库的魅力所在 🚀
【免费下载链接】formisch
The lightweight, schema-first, and fully type-safe form library for React, Solid, Vue, Svelte and more.
相关推荐
10分钟上手:NextUI+Auth.js打造React安全登录系统
10分钟上手:NextUI+Auth.js打造React安全登录系统 你还在为React应用的认证流程头疼吗?既要美观的UI界面,又要安全可靠的登录系统,如何快
前端UI组件设计系统5分钟快速上手Huh:打造你的第一个终端表单终极指南
5分钟快速上手Huh:打造你的第一个终端表单终极指南 Huh是一个简单而强大的Go语言库,专门用于在终端中构建交互式表单和提示。无论你是需要创建配置向导、用户输
开发工具UI组件3分钟终极指南:用Better ClearType Tuner彻底解决Windows字体模糊问题
3分钟终极指南:用Better ClearType Tuner彻底解决Windows字体模糊问题 你是不是经常在Windows系统上遇到字体模糊、边缘锯齿的问题
桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考