《用JSON造航母级表单!Formily Schema的终极防秃指南》

610 阅读2分钟

最近公司来了个新需求,要做一个能动态切换布局、跨页联动、支持撤回操作的表单系统。当我打开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——产品经理看了都想学!


第五章:血的教训(避坑指南)

  1. 嵌套地狱:object套array套object...建议超过3层就拆分
  2. 魔法表达式{{ }}里写JS时记得用$deps获取依赖值
  3. 性能陷阱:避免在顶层schema频繁修改,用合并策略优化
  4. 类型刺客:number类型的空值建议用null而不是undefined

终章:从青铜到王者路线图

  1. 青铜:手写基础表单
  2. 白银:实现动态联动
  3. 黄金:封装自定义组件
  4. 钻石:集成后端服务
  5. 王者:开发可视化schema设计器

友情提示:当你学会Schema后,可能会发生以下对话
产品经理:"这个需求..."
你:"把需求写成JSON发我"
产品经理:"???"
你:"或者我教你怎么写?(露出恶魔の微笑)"