Formily
按照formily官方文档,按照章节最小化复现
Install / Use
/learn @cgfeel/FormilyREADME
Formily Demo
按照 formily 官方文档,最小化复现每个示例。本项目不提供线上预览,请直接在本地运行npm install && npm run start
示例包含 4 个文档:
formily主文档:https://formilyjs.org/zh-CN@formily/reactive:https://reactive.formilyjs.org/zh-CN@formily/core:https://core.formilyjs.org/zh-CN@formily/react:https://react.formilyjs.org/zh-CN
其中组件采用 @formily/antd-v5 为主文档作演示。不包含 @formily/vue,技术栈为 React,在 formily 中两者大同小异
演示分两部分:
- 页面演示:
src/page目录下,下载安装安装依赖后npm run start - 单元测试:
src/__test__目录下,下载安装安装依赖后npm run test
所有示例根据自己理解添加了说明、并根据自己的理解补充示例;在文档最后补充两个作业:
- 一个第三方文档 fishedee 的
formily总结做一套练习 - 补充一个掘金练习:自增对象
工程文件
主要的使用的包:
- NodeJS:
v18.13.0 - 脚手架:
Create React App+react-app-rewired+customize-cra - 表单和UI库:
formily+antd+antd-style - 数据模拟:
mocker-api+mockjs
启动项目前需要先安装一次依赖:
npm install
和官方文档(以下简称“文档”)不同点:
- 采用
antd v5作为默认演示,文档默认是v4 - 采用
antd-style作为css-in-js框架,可以在这里查看详细演示 [查看] - 由于官方提供的
@formily/antd-v5采用的版本是5.6,很多 API 已发生变更,因此在演示组件中对部分组件重新修改 - 根据演示文件,根据自己的理解,重新调整了文件和目录结构
- 根据阅读的理解,添加个人附加案例
阅读说明
- 如上所述,
formily v2的Api会将个人解读,通过源码注释写在源码 - 而
README.md将会每个演示包含的注解,作为索引简要的罗列出来,方便查找 - 查找方法,每一个内容简介关联着对应示例,运行演示查找对应文件可以找到源码注释
示例
快速上手
- URL:
/start - 目录:https://github.com/cgfeel/formily/blob/main/src/page/Start.tsx
- 包含章节:
- 快速开始 [查看]
场景案例
登录注册
- URL:
/login - 目录:https://github.com/cgfeel/formily/blob/main/src/page/LoginRegister.tsx
- 包含章节:
- 登录注册 [查看]
包含:
通过Markup Schema创建登录:
- 验证模式:
createForm.validateFirst - 字段说明:
SchemaField.String,及相关属性- 关联反应:
SchemaField.reactions,主动受控和被动受控、受控依赖更新依赖组件状态
- 关联反应:
- 创建自定义表单组件
通过Json Schema创建登录
- 包含:
SchemaField.schema,使用JSON配置表单验证及其优点
通过JSX创建登录:
- 包括:
jsx和schema的不同,以及优缺点
通过Markup Schema创建注册:
- 组件:
ArrayItems、Cascader、DatePicker、Editable、FormGrid、FormItem、FormLayout、Password、Select、自定义组件IDUpload - 关联受控:作用域变量
$deps、$self,受控行为、路径查找 - 虚拟节点:充当
<Form.Item>,充当交互组件,虚拟节点和对象节点不同处
通过Json Schema创建注册:
- 通过
@emotion/styled来设置组件样式,从而解决Json Schema配置中无法使用antd-style的Hooks来配置组件样式
通过JSX创建注册:
Jsx自增控件路径查找- 由于
ArrayItems组件限定Schema场景,这里由ArrayField+ArrayBase代替,包括代替方案存在的问题
通过Markup Schema修改密码
通过Json Schema修改密码:
Json Schema中的key和表单name的关系
通过JSX修改密码
---- 分割线 ----
编辑详情
- URL:
/edit-detail - 目录:https://github.com/cgfeel/formily/blob/main/src/page/EditDetail.tsx
- 包含章节:
包含:
通过组件PreviewText.Placeholder实现预览:
- 默认全局预览方式
- 局部预览方式(下方查询列表[查看],个人补充了完整示例)
- 切换预览和编辑状态
- 表单组件根据可编辑状态受控响应(个人补充)
- 使用
useField获取可编辑状态
巩固(个人补充):
- 无论组件怎么拆分,每个表单声明
createForm只能匹配一个Form - 无法使用
useField以及无法通过受控获取可编辑状态时,可消费FormConsumer获取实时状态
无法在
Filed系列组件中通过component或decorator包裹的组件均无法受控、也不能使用useField,这也包过除此之外的所有React组件
---- 分割线 ----
查询列表
- URL:
/table - 目录:
- https://github.com/cgfeel/formily/blob/main/src/page/Grid.tsx
- https://github.com/cgfeel/formily/blob/main/src/page/Table.tsx
- 包含章节:
包含:
由于查询列表文档只提供了一个概念以及一个参考性的代码,这里按照要求实践:
QueryList:主要负责在顶层发请求QueryTable:一个ArrayTable,主要就是解析Schema子树,自己拼装出Table需要的Columns数QueryForm:负责查询筛选列表
为了实现这个需求,同时参考了两篇文档:
ArrayTable、FormGrid
概括:
FormConsumer消费数据更新改变提交状态ArrayTable的使用方法及总结、ArrayTable.Column的使用方法及总结SchemaField内的组件使用与React组件的不同- 通过
createForm实现主动受控和被动受控 - 受控中使用
when - 自定义组件
PriceInterval,和之前的不同的是这里还自定义了组件的onChange事件
---- 分割线 ----
弹窗与抽屉
- URL:
/dialog-drawer - 目录:https://github.com/cgfeel/formily/blob/main/src/page/DialogDrawer.tsx
- 包含章节:
包含:
演示了几个能力:
- 快速打开,关闭能力:通过
IFormDialog对象触发open和close - 中间件能力:
forCancel、forConfirm、forOpen(Drawer仅支持forOpen) - 渲染函数内可以响应式能力:
schema和Field - 上下文共享能力:仅限
Dialog
个人补充:
- 性能调优,通过拆分
schema和Field,具体见示例 Dialog和Drawer行为差异- 修复
Drawer适配问题
修复: 截止于 24.03.18
FormDrawer中使用antd v5的Dom结构和Api已发生更改,影响包括:FormDrawer.Extra和FormDrawer.Footer无效;可以拷贝这个组件并替换组件路径:https://github.com/cgfeel/formily/blob/main/src/components/drawer/form-drawer/index.tsx
---- 分割线 ----
分步表单
- URL:
/step-form - 目录:https://github.com/cgfeel/formily/blob/main/src/page/StepForm.tsx
- 包含章节:
包含:
FormStep.createFormStep和createForm一样,每次声明只能匹配一个form- 在前面登录示例中演示了
createSchemaField设置scope,分步表单演示了后置动态设置scope
---- 分割线 ----
选项卡、手风琴表单、自增选项卡、自增折叠表单
- URL:
/tab-collapse - 目录:https://github.com/cgfeel/formily/blob/main/src/page/TabCollapse.tsx
- 包含章节:
包含:
antd v5对于选项卡、手风琴表单、自增选项卡、自增折叠表单 API 的调整,以及交互操作- 巩固:
Json Schema中,对于需要为props传递上下文的情况,可以通过scope动态添加上下文对象 - 拆分
Markup Schema组件 及Json Schema
修复:
截止于 24.03.20,@formily/antd-v5部分组件 API 已废弃,我将其修复包括有:
FormTab:不再支持TabPane改为items[查看]FormCollapse:Api已发生更改,不再支持CollapsePane改为items[查看]ArrayCollapse:不再支持CollapsePane改为items[查看]
如果使用过程中官方仍旧没有修复,请查看对应的文件,拷贝修复
---- 分割线 ----
进阶指南
实现表单验证
- URL:
/validate - 目录:https://github.com/cgfeel/formily/blob/main/src/page/Validate.tsx
- 包含章节:
- 表单校验 [查看]
包含:
- 内置规则校验:
props,x-validator对象、x-validator数组对象 - 内置格式校验:
props,x-validator对象(字符、对象、字符数组、对象数组) - 自定义规则校验:
registerValidateRules - 自定义格式校验:
registerValidateFormats - 异步校验:自定义规则校验 +
Promise - 联动校验:
reactions - 定义文案:
registerValidateLocale
和文档不同:
- 自定义规则校验,
Json Schema是通过scope这个props动态添加局部定义规则;这样更符合实际应用场景 - 联动校验通过 3 种不同的方式进行:
createForm中的effects、schema中的x-reactions,Field中的reactions函数
---- 分割线 ----
实现表单布局
- URL:
/layout - 目录:https://github.com/cgfeel/formily/blob/main/src/page/Layout.tsx
- 包含章节:
包含:
Schema中使用自定义非表单组件- 根据
antd v5.15.*的 API 对组件进行修复 - 使用
antd v5自带的css-in-js添加组件样式 - 通过联动修改
FormItem的布局 - 为
Schema动态添加Component
组件修复:
Canscader:将接口对应至antd v5最新的 APIForm:为FormLayout提供上下文支持FormButtonGroup:适配FormLayoutFormItem:- 适配
FormLayout,补充必选样式 - 修复
Select.multiple、Switch在布局尺寸变更时的适配
- 适配
FormLayout:- 补充
layout: inline布局支持,修复必选等接口 - 添加布局样式支持
- 补充
原本是想为
@formily/antd-v5提交 PR,由于当前@formily/antd-v5依赖的是antd v5.6导致 API 不兼容,又不能修改工程依赖,所以采用这种方式进行修改
---- 分割线 ----
实现异步数据源
- URL:
/async - 目录:https://github.com/cgfeel/formily/blob/main/src/page/AsyncCom.tsx
- 包含章节:
包含:
Select同步获取数据、异步搜索、异步联动的三种模式(下方注1)TreeSelect同步获取数据、异步联动的三种模式Cascader异步数据三种模式
注1:总结中,所有提到的三种模式分别为:
Markup Schema、Json Schema、Field Jsx,如果没有单独说明,二种模式为:Markup Schema、Json Schema
个人补充案例:
TreeSelect异步加载数据三种模式Cascader修复静态数据加载 [查看]- 适配
antd v5最新版本中已废弃,而formily中又必须传入的属性
- 适配
Cascader异步加载数据三种模式- 对比异步数据不同的加载方式
异步数据加载方式:
- 初始只加载一次
- 依赖输入内容每次加载:
field.query({path}).value() - 通过
observable.ref创建引用劫持响应式对象 - 通过
scope初始只加载一次 - 通过
scope依赖输入内容每次加载
---- 分割线 ----
实现表单受控
- URL:
/controlled - 目录:https://github.com/cgfeel/formily/blob/main/src/page/Controlled.tsx
- 包含章节:
- 实现表单受控 [查看]
几个受控模式:
- 普通受控模式,随 React 组件生命周期,演示:只存在控制者、通过
props受控、通过ref受控 - 响应式值受控:使用
observable提供数据用于响应受控 Schema整体受控:通过替换整个form和schema实现表单整体切换Schema片段联动:- 通过
form.clearFormGraph回收字段模型,从而实现部分表单更新 - 通过 `observ
- 通过
Related Skills
bluebubbles
352.0kUse when you need to send or manage iMessages via BlueBubbles (recommended iMessage integration). Calls go through the generic message tool with channel="bluebubbles".
node-connect
352.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
slack
352.0kUse when you need to control Slack from OpenClaw via the slack tool, including reacting to messages or pinning/unpinning items in Slack channels or DMs.
frontend-design
111.1kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
