在后端管理系统开发中,表单无处不在,却也最容易成为性能瓶颈和逻辑黑洞。当你需要处理包含数十个字段、复杂动态联动和嵌套校验的“怪兽级”表单时,是否感到力不从心?
如果还在依赖大量的 useState 和 useEffect 手动维护状态,或者为了一个字段的变化而触发整个表单的重渲染,那么,是时候了解一下更高效的解决方案了。
2026年初,Formily v2.3.0 正式发布,核心引擎经过重写,带来了显著的性能提升。作为阿里巴巴开源的企业级表单解决方案,它正以其数据+协议驱动的理念,重新定义复杂表单的开发模式。
Formily 是一套基于分层架构的高性能表单解决方案。它的核心理念在于将表单的业务逻辑与UI渲染彻底解耦。
- 框架无关:同时支持 React 和 Vue,甚至可以应用于 React Native 场景。
- 协议驱动:你可以通过一份标准的 JSON Schema 来完整描述表单的UI结构、校验规则和字段间的联动逻辑。
- 高性能:采用响应式编程模型,实现了字段级精准更新。在输入和联动场景下,其时间复杂度为 O(1),这意味着性能不会随着表单字段数量的增加而下降。
简而言之,Formily = 表单状态管理引擎 + UI桥接层 + 丰富的组件生态。
面对复杂表单,开发者通常有以下几种选择,而Formily的诞生正是为了解决它们的固有缺陷:
- 非受控组件:实现简单,但无法实时监听值变化,复杂的校验和联动逻辑难以维护。
- 受控组件:通过
setState 管理状态,逻辑清晰,但在大型表单中,任何一个字段的更新都可能导致整个表单树重渲染(时间复杂度O(n)),性能开销巨大。
- Formily方案:抽象出 Form 和 Field 两级状态,采用发布/订阅模式和响应式原理。无论表单有多少字段,操作单一字段时只会触发其自身的更新,将性能复杂度牢牢控制在 O(1)。
核心优势
- 极致性能:v2.3.0 版本对路径解析和依赖追踪进行了深度优化。即使在包含数千个字段的表单中,针对单个字段的高频输入操作也能保持流畅。
- 强大的声明式联动:无论是控制字段显隐、禁用状态,还是动态修改组件属性、校验规则,都可以通过声明式的
x-reactions 轻松实现。你只需关心数据之间的依赖关系,UI的同步更新由框架自动完成。
- 完善的生态集成:官方提供了 Ant Design、Element UI 等主流组件库的桥接包。这意味着你可以继续使用熟悉的UI组件,同时享受 Formily 强大的状态管理能力。
- 可视化搭建能力:配合 Designable 可视化设计器,可以通过拖拽方式生成复杂表单,并直接导出可运行的 JSON Schema,为低代码平台建设提供了强大支持。
需要了解的局限性
- 学习曲线较陡:引入了协议、响应式、领域模型等概念,新手需要时间理解
Field、Schema、Reactions 等核心API。
- 包体积较大:作为一套完整的解决方案,压缩后体积约80KB左右,对极致追求首屏加载速度的场景需要权衡。
- 浏览器兼容性:其响应式机制依赖于现代 JavaScript 特性,因此无法支持 Internet Explorer 浏览器。
理论说了这么多,我们通过一个实际例子来感受一下。以下以 React + Ant Design 技术栈为例,演示如何快速创建一个基础登录表单。
1. 安装依赖
首先,安装 Formily 的核心库、React 桥接层以及 Ant Design 组件桥接库。
npm install --save @formily/core @formily/react
npm install --save antd @formily/antd
2. 使用 JSON Schema 模式开发
Formily 支持多种开发模式,其中 JSON Schema 模式 最为灵活和强大。它允许你将表单的UI和逻辑完全用一份 JSON 来描述。
假设我们要创建一个包含用户名和密码的登录表单:
import React from ‘react’;
import { createForm } from ‘@formily/core’;
import { FormProvider, createSchemaField } from ‘@formily/react’;
import { FormItem, Input, FormButtonGroup, Submit } from ‘@formily/antd’;
// 1. 创建表单核心实例,管理所有状态
const form = createForm();
// 2. 创建 SchemaField 渲染器,并注册要使用的组件
const SchemaField = createSchemaField({
components: {
FormItem,
Input, // 这里使用的是 @formily/antd 包装过的 Input 组件
},
});
// 3. 定义 JSON Schema,描述表单结构
const schema = {
type: ‘object’,
properties: {
username: {
type: ‘string’,
title: ‘用户名’,
required: true,
‘x-decorator’: ‘FormItem’, // 指定包装组件
‘x-component’: ‘Input’, // 指定输入组件
‘x-component-props’: { // 传递给组件的属性
placeholder: ‘请输入用户名’,
},
},
password: {
type: ‘string’,
title: ‘密码’,
required: true,
‘x-decorator’: ‘FormItem’,
‘x-component’: ‘Input’,
‘x-component-props’: {
placeholder: ‘请输入密码’,
type: ‘password’, // 设置为密码输入框
},
},
},
};
export default () => {
const handleSubmit = (values) => {
console.log(‘表单提交值:’, values); // 在这里获取校验通过的表单数据
};
return (
<FormProvider form={form}>
{/* 核心:根据 Schema 渲染表单 */}
<SchemaField schema={schema} />
<FormButtonGroup>
<Submit onSubmit={handleSubmit}>提交</Submit>
</FormButtonGroup>
</FormProvider>
);
};
代码解读:
createForm():初始化表单领域模型,是所有状态变化的源头。
FormProvider:通过 React Context 将上方的 form 实例传递给下层组件。
SchemaField:核心渲染器,负责解析我们定义的 schema JSON对象,并将其递归渲染成真实的表单组件树。
- 数据获取:表单校验通过后,提交按钮的
onSubmit 回调函数中即可拿到结构化的表单数据。
3. 实现进阶字段联动
Formily 的精华在于其强大的联动能力。例如,实现一个常见的场景:一个复选框控制另一个输入框的显示与隐藏。
// 在 schema 的 properties 中增加联动字段
const schema = {
properties: {
// …… 其他基础字段
showExtra: {
type: ‘boolean’,
title: ‘显示额外信息’,
‘x-decorator’: ‘FormItem’,
‘x-component’: ‘Checkbox’, // 需要提前注册 Checkbox 组件
},
extraInfo: {
type: ‘string’,
title: ‘额外信息’,
‘x-decorator’: ‘FormItem’,
‘x-component’: ‘Input’,
‘x-reactions’: [ // 联动规则定义在这里
{
dependencies: [‘showExtra’], // 声明依赖于 showExtra 字段的值
fulfill: {
state: {
// 当依赖的字段值不为 true 时,将当前字段隐藏
hidden: ‘{{$deps[0] !== true}}’,
},
},
},
],
},
},
};
通过 x-reactions 属性,我们以声明式的方式定义了 extraInfo 字段的显示逻辑依赖于 showExtra 字段的值。整个过程无需编写任何 useEffect 监听函数,逻辑清晰且维护方便。这正是 JSON Schema 和响应式编程的魅力所在。
四、生态与展望
Formily 的强大,不仅在于其内核,更在于其围绕 Designable 构建的生态系统。如果你觉得手写 Schema 也有一定成本,可以尝试 @designable/formily-antd 等可视化搭建工具。它允许你通过拖拽组件的方式,像搭积木一样设计表单,并直接导出可用于生产环境的 Schema。这对于需要快速构建原型或搭建低代码平台的项目来说,价值巨大。
结语
Formily v2.3.0 凭借其响应式内核、协议驱动的开发模式以及卓越的联动性能,为复杂中后台表单开发提供了一套成熟的解决方案。尽管初期需要投入一些学习成本,但它能从根本上解决表单开发的维护性和性能痛点。
如果你的项目正被动态表单、复杂校验和联动逻辑所困扰,不妨尝试一下 Formily,体验其声明式开发和极致的运行时性能。欢迎在 云栈社区 的前端板块交流你的使用心得或遇到的挑战。