最近公司来了个新需求,要做一个能动态切换布局、跨页联动、支持撤回操作的表单系统。当我打开GitHub准备写遗书时,突然发现Formily的Schema JSON——这玩意居然能用JSON写出会跳舞的表单?!
第0章:给产品经理看的说明书
产品经理:"我要一个能根据天气变化背景色的表单!"
程序员:"亲,建议您直接看本文第三节第2条呢~"
第一章:Schema入门补习班
1.1 什么是魔法契约书?
Formily Schema就是一份JSON格式的表单说明书,包含:
- 字段地图(哪些输入项)
- 交互指南(怎么联动)
- 皮肤设定(用什么组件)
json
复制
// 举个栗子:相亲登记表
{
"type": "object",
"properties": {
"name": {
"title": "你的名字",
"type": "string",
"x-component": "Input",
"required": true
},
"age": {
"title": "芳龄几何",
"type": "number",
"x-component": "NumberPicker",
"minimum": 18
}
}
}
1.2 核心黑科技:x-魔法前缀
x-component:指定组件(Input/Select等)x-decorator:组件包装器(表单布局)x-reactions:触发联动效果x-validator:校验规则
第二章:实战代码马戏团
2.1 基础三连:输入、选择、布局
{
"type": "object",
"properties": {
"username": {
"type": "string",
"title": "用户名",
"x-component": "Input",
"x-decorator": "FormItem" // 自动布局
},
"gender": {
"type": "string",
"title": "性别",
"enum": ["男", "女", "保密"],
"x-component": "Radio.Group"
}
}
}
2.2 动态联动:让字段跳街舞
"hasCar": {
"type": "boolean",
"title": "是否有车",
"x-component": "Switch",
"x-reactions": [
{
// 当开关打开时,显示车牌字段
"when": "{{ $self.value }}",
"target": "licensePlate",
"fulfill": {
"state": { "visible": true }
}
}
]
}
2.3 跨字段监听:玩转数据关系
"password": {
"type": "string",
"title": "密码",
"x-component": "Password"
},
"confirmPassword": {
"type": "string",
"title": "确认密码",
"x-component": "Password",
"x-reactions": [
{
// 实时校验两次输入是否一致
"dependencies": ["password"],
"fulfill": {
"schema": {
"x-validator": "{{ $deps[0] === $self.value ? '' : '两次密码不一致' }}"
}
}
}
]
}
2.4 自定义组件:召唤神龙
"weather": {
"type": "string",
"title": "今日天气",
"x-component": "MagicWeatherPicker", // 你的自定义组件
"x-component-props": {
"showRainbow": true
}
}
第三章:高阶操作の禁忌魔法
3.1 循环渲染:生成动态表格
"employees": {
"type": "array",
"title": "员工列表",
"x-component": "ArrayTable",
"items": {
"type": "object",
"properties": {
"name": { "type": "string", "x-component": "Input" },
"age": { "type": "number", "x-component": "NumberPicker" }
}
}
}
3.2 远程加载:异步加载选项
"city": {
"type": "string",
"title": "城市",
"x-component": "Select",
"x-component-props": {
"service": "{{ fetchCityList }}" // 异步获取选项
}
}
3.3 条件格式:智能变色龙
"score": {
"type": "number",
"title": "考试分数",
"x-reactions": [
{
"when": "{{ $self.value < 60 }}",
"fulfill": {
"schema": {
"x-component-props": { "style": { "color": "red" } }
}
}
}
]
}
第四章:防秃顶最佳实践
4.1 模块化设计:拆分魔法卷轴
// 把地址选择器拆成独立schema
const addressSchema = {
province: { /*...*/ },
city: { /*...*/ },
detail: { /*...*/ }
}
// 主schema中引用
"deliveryAddress": {
"type": "object",
"properties": addressSchema
}
4.2 调试技巧:开启上帝模式
<SchemaForm
schema={yourSchema}
onFormSubmit={(values) => console.log(values)}
effects={() => {
// 实时监听表单变化
onFieldValueChange$().subscribe(field => {
console.log('字段变化:', field)
})
}}
/>
4.3 可视化工具:低代码保平安
官方提供的Schema可视化编辑器,让你用拖拽生成schema——产品经理看了都想学!
第五章:血的教训(避坑指南)
- 嵌套地狱:object套array套object...建议超过3层就拆分
- 魔法表达式:
{{ }}里写JS时记得用$deps获取依赖值 - 性能陷阱:避免在顶层schema频繁修改,用合并策略优化
- 类型刺客:number类型的空值建议用
null而不是undefined
终章:从青铜到王者路线图
- 青铜:手写基础表单
- 白银:实现动态联动
- 黄金:封装自定义组件
- 钻石:集成后端服务
- 王者:开发可视化schema设计器
友情提示:当你学会Schema后,可能会发生以下对话
产品经理:"这个需求..."
你:"把需求写成JSON发我"
产品经理:"???"
你:"或者我教你怎么写?(露出恶魔の微笑)"