From cb7f095dcbb35d864e58751862d4917e04c69d0c Mon Sep 17 00:00:00 2001 From: kenve Date: Thu, 2 Apr 2020 23:10:23 +0800 Subject: [PATCH] docs: formatted with prettier (#768) * docs: formatted with prettier * chore: add prettier auto-formatting on commit --- README.md | 6 +- README.zh-cn.md | 11 +- docs/en-us/SUMMARY.md | 26 +- docs/zh-cn/README.md | 17 +- docs/zh-cn/SUMMARY.md | 11 +- docs/zh-cn/contributor.md | 100 +- docs/zh-cn/devtools.md | 5 +- docs/zh-cn/introduction/comparison.md | 2 +- docs/zh-cn/introduction/formily.md | 71 +- docs/zh-cn/jsx-develop/complex-linkage.md | 18 +- docs/zh-cn/jsx-develop/faq.md | 77 +- docs/zh-cn/jsx-develop/form-path.md | 8 +- docs/zh-cn/jsx-develop/introduction.md | 2 +- docs/zh-cn/jsx-develop/lifecycle.md | 64 +- docs/zh-cn/jsx-develop/linkage-validate.md | 2 +- docs/zh-cn/jsx-develop/manage-business.md | 2 +- docs/zh-cn/jsx-develop/quick-start.md | 13 +- docs/zh-cn/jsx-develop/self-inc-component.md | 267 +-- docs/zh-cn/other-links.md | 2 +- docs/zh-cn/schema-develop/actions-effects.md | 6 +- docs/zh-cn/schema-develop/complex-linkage.md | 4 +- .../complext-self-inc-component.md | 726 ++++---- .../create-complex-field-component.md | 2 +- docs/zh-cn/schema-develop/form-extension.md | 10 +- docs/zh-cn/schema-develop/form-graph.md | 2 +- docs/zh-cn/schema-develop/form-path.md | 16 +- docs/zh-cn/schema-develop/form-schema.md | 2 +- docs/zh-cn/schema-develop/form-value.md | 7 +- docs/zh-cn/schema-develop/introduction.md | 8 +- docs/zh-cn/schema-develop/lifecycle.md | 71 +- docs/zh-cn/schema-develop/manage-business.md | 72 +- docs/zh-cn/uform-upgrade.md | 1 - package.json | 4 + packages/antd-components/README.zh-cn.md | 930 +++++----- packages/antd/README.zh-cn.md | 1137 ++++++------ packages/core/README.md | 6 +- packages/core/README.zh-cn.md | 24 +- packages/meet-components/README.md | 2 - packages/meet-components/README.zh-cn.md | 630 +++---- packages/meet/README.md | 2 - packages/meet/README.zh-cn.md | 852 ++++----- packages/next-components/README.zh-cn.md | 952 +++++----- packages/next/README.zh-cn.md | 1183 +++++++------ packages/printer/README.md | 3 +- packages/react-schema-editor/README.md | 326 ++-- packages/react-schema-renderer/README.md | 33 +- .../react-schema-renderer/README.zh-cn.md | 38 +- packages/react-shared-components/README.md | 3 +- packages/react/README.md | 1532 +++++++++-------- packages/react/README.zh-cn.md | 1530 +++++++++------- packages/shared/README.md | 3 +- packages/validator/README.md | 3 +- 52 files changed, 5689 insertions(+), 5135 deletions(-) diff --git a/README.md b/README.md index 66fa4194630..39bbc0faf20 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,6 @@ npm install --save @formily/core ![](https://img.alicdn.com/tfs/TB1BvlRu4D1gK0jSZFsXXbldVXa-1882-1144.png) - ## WebSite https://formilyjs.org @@ -72,7 +71,6 @@ https://formilyjs.org - [@formily/react](./packages/react/README.md) - [@formily/core](./packages/core/README.md) - ## Demo [codesandbox](https://codesandbox.io/s/o5up7) @@ -81,13 +79,11 @@ https://formilyjs.org - [icejs](https://github.com/alibaba/ice) - ## Contributors -This project exists thanks to all the people who contribute. +This project exists thanks to all the people who contribute. - ## LICENSE Formily is open source software licensed as diff --git a/README.zh-cn.md b/README.zh-cn.md index c38a29f1d3a..7cc3cd552db 100644 --- a/README.zh-cn.md +++ b/README.zh-cn.md @@ -13,7 +13,7 @@ ## 背景 -在React中,在受控模式下,表单的整树渲染问题非常明显。特别是对于数据联动的场景,很容易导致页面卡顿,为了解决这个问题,我们将每个表单字段的状态做了分布式管理,从而大大提升了表单操作性能。同时,我们深度整合了JSON Schema协议,可以帮助您快速解决后端驱动表单渲染的问题。 +在 React 中,在受控模式下,表单的整树渲染问题非常明显。特别是对于数据联动的场景,很容易导致页面卡顿,为了解决这个问题,我们将每个表单字段的状态做了分布式管理,从而大大提升了表单操作性能。同时,我们深度整合了 JSON Schema 协议,可以帮助您快速解决后端驱动表单渲染的问题。 ## 特性 @@ -37,13 +37,13 @@ npm install --save antd @formily/antd @formily/antd-components npm install --save @alifd/next @formily/next @formily/next-components ``` -使用Formily React渲染引擎包: +使用 Formily React 渲染引擎包: ```bash npm install --save @formily/react-schema-renderer ``` -使用 Formily React包: +使用 Formily React 包: ```bash npm install --save @formily/react @@ -71,7 +71,6 @@ https://formilyjs.org - [@formily/react](./packages/react/README.zh-cn.md) - [@formily/core](./packages/core/README.zh-cn.md) - ## 入门案例 [codesandbox](https://codesandbox.io/s/o5up7) @@ -80,13 +79,11 @@ https://formilyjs.org - [icejs](https://github.com/alibaba/ice) - ## 贡献者 -This project exists thanks to all the people who contribute. +This project exists thanks to all the people who contribute. - ## LICENSE Formily is open source software licensed as diff --git a/docs/en-us/SUMMARY.md b/docs/en-us/SUMMARY.md index 4d2b94515cc..2231ee34dc0 100644 --- a/docs/en-us/SUMMARY.md +++ b/docs/en-us/SUMMARY.md @@ -1,19 +1,19 @@ - [首页](./README.md) -- Schema开发指南 +- Schema 开发指南 - 介绍 - 快速开始 - 概念/术语理解 - 理解表单生命周期 - - 理解actions/effects + - 理解 actions/effects - 理解表单路径系统 - 理解传值属性 - 理解表单节点树 - 理解表单组件扩展机制 - 实践教程 - 使用布局组件 - - 使用Effect Hooks - - 自定义Effect Hook - - 借助Rxjs实现联动逻辑 + - 使用 Effect Hooks + - 自定义 Effect Hook + - 借助 Rxjs 实现联动逻辑 - 实现超复杂联动逻辑 - 实现联动校验 - 跨组件操作表单 @@ -34,15 +34,15 @@ - 快速开始 - 概念/术语理解 - 理解表单生命周期 - - 理解actions/effects + - 理解 actions/effects - 理解表单路径系统 - 理解传值属性 - 理解表单节点树 - 实践教程 - 使用布局组件 - - 使用Effect Hooks - - 自定义Effect Hook - - 借助Rxjs实现联动逻辑 + - 使用 Effect Hooks + - 自定义 Effect Hook + - 借助 Rxjs 实现联动逻辑 - 实现超复杂联动逻辑 - 实现联动校验 - 跨组件操作表单 @@ -56,17 +56,17 @@ - 其他指南 - 底层扩展开发 - 介绍 - - 理解核心API - - 理解Observable Graph + - 理解核心 API + - 理解 Observable Graph - 扩展实现@formily/vue - 扩展实现@formily/mini-app - FAQ - 升级迁移指南 - - UForm迁移Formily + - UForm 迁移 Formily - 开发调试指南 - devtools - 贡献指南 -- API手册 +- API 手册 - Ant Design - antd - antd-components diff --git a/docs/zh-cn/README.md b/docs/zh-cn/README.md index df47ca5e613..fa83668752d 100644 --- a/docs/zh-cn/README.md +++ b/docs/zh-cn/README.md @@ -1,7 +1,6 @@ - ## 背景 -在React中,在受控模式下,表单的整树渲染问题非常明显。特别是对于数据联动的场景,很容易导致页面卡顿,为了解决这个问题,我们将每个表单字段的状态做了分布式管理,从而大大提升了表单操作性能。同时,我们深度整合了JSON Schema协议,可以帮助您快速解决后端驱动表单渲染的问题。 +在 React 中,在受控模式下,表单的整树渲染问题非常明显。特别是对于数据联动的场景,很容易导致页面卡顿,为了解决这个问题,我们将每个表单字段的状态做了分布式管理,从而大大提升了表单操作性能。同时,我们深度整合了 JSON Schema 协议,可以帮助您快速解决后端驱动表单渲染的问题。 ## 特性 @@ -25,13 +24,13 @@ npm install --save antd @formily/antd npm install --save @alifd/next @formily/next ``` -使用Formily React渲染引擎包: +使用 Formily React 渲染引擎包: ```bash npm install --save @formily/react-schema-renderer ``` -使用 Formily React包: +使用 Formily React 包: ```bash npm install --save @formily/react @@ -45,17 +44,15 @@ npm install --save @formily/core ## 社区 - -| Online Chat Room | 微信 | 钉钉 | -| ------------------------------------------------------------ | ------------------------------------------------------------ | ---- | -| [gitter.im](https://gitter.im/alibaba-formily/community?source=orgpage) | | | +| Online Chat Room | 微信 | 钉钉 | +| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | +| [gitter.im](https://gitter.im/alibaba-formily/community?source=orgpage) | | | ## 贡献者 -This project exists thanks to all the people who contribute. +This project exists thanks to all the people who contribute. - ## LICENSE Formily is open source software licensed as diff --git a/docs/zh-cn/SUMMARY.md b/docs/zh-cn/SUMMARY.md index 070734460cb..aec13a3c59d 100644 --- a/docs/zh-cn/SUMMARY.md +++ b/docs/zh-cn/SUMMARY.md @@ -1,14 +1,13 @@ - - 首页 - - [Formily是什么](./introduction/formily.md) + - [Formily 是什么](./introduction/formily.md) - [竞品对比](./introduction/comparison.md) - Schema Form - [介绍](./schema-develop/introduction.md) - [快速开始](./schema-develop/quick-start.md) - 概念/术语理解 - - [理解Form Schema](./schema-develop/form-schema.md) + - [理解 Form Schema](./schema-develop/form-schema.md) - [理解表单生命周期](./schema-develop/lifecycle.md) - - [理解actions/effects](./schema-develop/actions-effects.md) + - [理解 actions/effects](./schema-develop/actions-effects.md) - [理解表单路径系统](./schema-develop/form-path.md) - [理解传值属性](./schema-develop/form-value.md) - [理解表单状态](./schema-develop/form-state.md) @@ -28,7 +27,7 @@ - [快速开始](./jsx-develop/quick-start.md) - 概念/术语理解 - [理解表单生命周期](./jsx-develop/lifecycle.md) - - [理解actions/effects](./jsx-develop/actions-effects.md) + - [理解 actions/effects](./jsx-develop/actions-effects.md) - [理解表单路径系统](./jsx-develop/form-path.md) - [理解传值属性](./jsx-develop/form-value.md) - [理解表单状态](./jsx-develop/form-state.md) @@ -43,7 +42,7 @@ - [FAQ](./jsx-develop/faq.md) - Help - 升级迁移指南 - - [UForm迁移Formily](./uform-upgrade.md) + - [UForm 迁移 Formily](./uform-upgrade.md) - 开发调试指南 - [Chrome Devtools](./devtools.md) - [其他文档/资料](./other-links.md) diff --git a/docs/zh-cn/contributor.md b/docs/zh-cn/contributor.md index 0b06d86a0ab..e0e5cd110d3 100644 --- a/docs/zh-cn/contributor.md +++ b/docs/zh-cn/contributor.md @@ -6,48 +6,55 @@ ## 我可以贡献什么? -* features 新增/修改功能特性 -* unitest 新增/修改单测 -* bugfix 修复现有issue的问题 -* doc 文档改进 -* other 其他 +- features 新增/修改功能特性 +- unitest 新增/修改单测 +- bugfix 修复现有 issue 的问题 +- doc 文档改进 +- other 其他 ## 如何贡献? #### 拉取仓库 -* 原始仓库:https://github.com/alibaba/formily -* 目标仓库:folk到自己的github上 -![](https://img.alicdn.com/tfs/TB1NLrjxXY7gK0jSZKzXXaikpXa-2206-490.png) + +- 原始仓库:https://github.com/alibaba/formily +- 目标仓库:fork 到自己的 github 上 + ![](https://img.alicdn.com/tfs/TB1NLrjxXY7gK0jSZKzXXaikpXa-2206-490.png) #### 拉取分支 -原始分支是 alibaba/formily master ,拉取后的分支应该是 quirkyshop/formily master + +原始分支是 alibaba/formily master,拉取后的分支应该是 quirkyshop/formily master + > 注意:建议分支名为[feat]-[name],[feat]是这个分支的类型,可选的有[feat][unitest][doc][bugfix][other],[name]则是名字,自定义就好了。eg. unittest-core(意为:对核心补充单测) #### 提交代码 -​ -代码风格遵循2空格,无分号,非说明请不要在代码中附带任何console相关的方法及debugger。 -开发完成后,到自己folk出来的仓库提交pull request + +代码风格遵循 2 空格,无分号,非说明请不要在代码中附带任何 console 相关的方法及 debugger。 +开发完成后,到自己 fork 出来的仓库提交 pull request ![](https://img.alicdn.com/tfs/TB1HSvqxkT2gK0jSZFkXXcIQFXa-2050-898.png) ![](https://img.alicdn.com/tfs/TB1O.6mxbr1gK0jSZR0XXbP8XXa-1696-254.png) -> 注意这里的左边目标仓库(base repository是 alibaba/formily master) ,然后右边当前分支自己仓库的 doc-wiki -#### PR规范 +> 注意这里的左边目标仓库(base repository 是 alibaba/formily master) ,然后右边当前分支自己仓库的 doc-wiki + +#### PR 规范 + 参考文档:https://github.com/alibaba/formily/blob/master/.github/GIT_COMMIT_SPECIFIC.md -* PR名称:格式:`(): ` 举例:`feat(core): add unit test` -* PR内容:列举本次改动的内容 -* PR要求:增加的feat内容,尽量做到注释清晰,相应的单测覆盖要尽可能覆盖 -* BUGFIX要求:如果修改的问题和issues相关,请在内容中附上相关的issueID。 + +- PR 名称:格式:`(): ` 举例:`feat(core): add unit test` +- PR 内容:列举本次改动的内容 +- PR 要求:增加的 feat 内容,尽量做到注释清晰,相应的单测覆盖要尽可能覆盖 +- BUGFIX 要求:如果修改的问题和 issues 相关,请在内容中附上相关的 issueID。 #### 审核与合并 -审核阶段会进入多review的流程,`@janryWang` 负责审核这个改动是否合并,其他同学也会参与讨论,讨论的经过都会留存在github的PR里,钉钉群也会收到相应的通知。 -当看到PullRequests列表中的状态变为closed即为合并成功。 +审核阶段会进入多 review 的流程,`@janryWang` 负责审核这个改动是否合并,其他同学也会参与讨论,讨论的经过都会留存在 github 的 PR 里,钉钉群也会收到相应的通知。 + +当看到 Pull requests 列表中的状态变为 Closed 即为合并成功。 ![](https://img.alicdn.com/tfs/TB1HUnjxXY7gK0jSZKzXXaikpXa-964-104.png) -#### 同步源仓库变更到folk后的仓库 +#### 同步源仓库变更到 fork 后的仓库 ```shell -# 首先在自己的分支增加一个upstream,即原仓库 +# 首先在自己的分支增加一个 upstream,即原仓库 $ git remote add upstream https://github.com/alibaba/formily.git # 获取原仓库最新的变更 $ git fetch upstream @@ -56,43 +63,52 @@ $ git pull upstream master [当前本地目标分支,不填默认就是当前 ``` #### 项目开发 -拉取目录到本地后,需要安装依赖,并且由于是多项目管理,互相有依赖,需要用lerna来做到 + +拉取目录到本地后,需要安装依赖,并且由于是多项目管理,互相有依赖,需要用 lerna 来做到 + ```shell $ cd formily -$ npm install #安装整体项目依赖 -$ npm run build #先跑一遍构建 +$ npm install # 安装整体项目依赖 +$ npm run build # 先跑一遍构建 $ npm run bootstrap # 安装子项目依赖 -$ npm run build #各自构建子项目lib +$ npm run build # 各自构建子项目lib ``` #### 目录结构 -* core 核心层 -* react UI层,react实现 -* validator 校验器 -* shared 公共逻辑 -* react-shared-component 通用视图组件层 -* react-schema-editor 可视化Schema编辑器 -* react-schema-renderer Schema渲染组件 -* antd/next/meet 生态层 -* antd/next/meet-components 生态组件层 -* printer Schema打印组件 -* devtools 浏览器插件 -* ... + +- core 核心层 +- react UI 层,react 实现 +- validator 校验器 +- shared 公共逻辑 +- react-shared-component 通用视图组件层 +- react-schema-editor 可视化 Schema 编辑器 +- react-schema-renderer Schema 渲染组件 +- antd/next/meet 生态层 +- antd/next/meet-components 生态组件层 +- printer Schema 打印组件 +- devtools 浏览器插件 +- ... #### 开发模式 -举例说明,现在开发core,想要比较有体感的使用某个core的API + +举例说明,现在开发 core,想要比较有体感的使用某个 core 的 API + ```shell $ cd formily -$ npm run doc:core # 查看core的demo展示,目录位于 packages/core/README.md +$ npm run doc:core # 查看 core 的 demo 展示,目录位于 packages/core/README.md ``` + 此时编辑 packages/core/README.md 会在 `watch` 模式下看到 `demo` 的改变,方便直观感受和修改代码 > 更多开发模式请参考源码,我们在各个目录下都提供了示例 `README.md` 的 `demo` 。 #### 单元测试 -举例说明,现在对core进行单测覆盖 + +举例说明,现在对 core 进行单测覆盖 + ```shell $ cd formily $ npm run test:core # 会执行 packages/core/src/__test__ 下的单元测试 ``` -> 更多单测形式请参考源码,我们已在源码中提供超过200个单元测试! + +> 更多单测形式请参考源码,我们已在源码中提供超过 200 个单元测试! diff --git a/docs/zh-cn/devtools.md b/docs/zh-cn/devtools.md index c811477c723..46d7e016799 100644 --- a/docs/zh-cn/devtools.md +++ b/docs/zh-cn/devtools.md @@ -1,6 +1,6 @@ -# Formily Chrome Devtools +# Formily Chrome Devtools -目前提供了chrome扩展开发者工具,可以帮助用户方便的查看状态树 +目前提供了 chrome 扩展开发者工具,可以帮助用户方便的查看状态树 ## 下载地址 @@ -9,4 +9,3 @@ https://chrome.google.com/webstore/detail/formily-devtools/kkocalmbfnplecdmbadaa ## 预览 ![](https://img.alicdn.com/tfs/TB1fnoEvVP7gK0jSZFjXXc5aXXa-2146-1584.png) - diff --git a/docs/zh-cn/introduction/comparison.md b/docs/zh-cn/introduction/comparison.md index f5d0e949e68..3095ab34bb2 100644 --- a/docs/zh-cn/introduction/comparison.md +++ b/docs/zh-cn/introduction/comparison.md @@ -1 +1 @@ -# 竞品对比 \ No newline at end of file +# 竞品对比 diff --git a/docs/zh-cn/introduction/formily.md b/docs/zh-cn/introduction/formily.md index 63ed3266ef7..f62405d575d 100644 --- a/docs/zh-cn/introduction/formily.md +++ b/docs/zh-cn/introduction/formily.md @@ -1,52 +1,42 @@ -# Formily是什么? +# Formily 是什么? +Formily 是一个由阿里巴巴集团多 BU 共建的面向中后台复杂场景的表单解决方案,它也是一个表单框架。 +它的前身是供应链平台在 2019 年初对外开源的 UForm 解决方案,UForm 的前身又是在供应链平台内部自研的某个表单框架。 -Formily是一个由阿里巴巴集团多BU共建的面向中后台复杂场景的表单解决方案,它也是一个表单框架。 +总体来看,Formily 是一个经过了漫长时间所磨炼,沉淀出来的表单解决方案。 -它的前身是供应链平台在2019年初对外开源的UForm解决方案,UForm的前身又是在供应链平台内部自研的某个表单框架。 - -总体来看,Formily是一个经过了漫长时间所磨炼,沉淀出来的表单解决方案。 - -同时,我们在集团内部,也有着最复杂的表单场景一直持续在挑战着Formily的极限。 - -所以,Formily发展到现在,完全是受业务而推进的解决方案,**这不是一个简单的前端轮子!** - -这是一个真正意义上,为业务而生的表单解决方案!只要阿里巴巴还有中后台表单场景,Formily就会一直持续维护下去。 +同时,我们在集团内部,也有着最复杂的表单场景一直持续在挑战着 Formily 的极限。 +所以,Formily 发展到现在,完全是受业务而推进的解决方案,**这不是一个简单的前端轮子!** +这是一个真正意义上,为业务而生的表单解决方案!只要阿里巴巴还有中后台表单场景,Formily 就会一直持续维护下去。 ## 面临什么问题 -在阿里巴巴集团正式开始打响中后台战役之后,阿里内部各种中后台系统如雨后春笋般猛烈发展,面向B端的业务场景越来越大,也越来越厚重,对于阿里前端工程师而言,即是压力也是机遇,压力是,我们要开发的页面会更多,我们要解决的问题也会更多,如何给商家赋能?又如何给内部用户提效?机遇则是,我们迎来了新的前端蓝海,所以,阿里的Ant Design到Fusion Next再到ICE这一系列的解决方案油然而生。 - +在阿里巴巴集团正式开始打响中后台战役之后,阿里内部各种中后台系统如雨后春笋般猛烈发展,面向 B 端的业务场景越来越大,也越来越厚重,对于阿里前端工程师而言,即是压力也是机遇,压力是,我们要开发的页面会更多,我们要解决的问题也会更多,如何给商家赋能?又如何给内部用户提效?机遇则是,我们迎来了新的前端蓝海,所以,阿里的 Ant Design 到 Fusion Next 再到 ICE 这一系列的解决方案油然而生。 - -但是,我们却始终面临一个心头之痛,表单,在中后台场景下,80%以上的页面,都是由表单组成,每个表单又是由各种形态的表单输入项所组成,当我们有了Ant Design/Fusion Next之后,我们可以轻松做到不需要关心表单输入项内部的复杂交互逻辑了,只需要关注如何组装表单页面即可,这就是组件化所带来的强大赋能。 +但是,我们却始终面临一个心头之痛,表单,在中后台场景下,80%以上的页面,都是由表单组成,每个表单又是由各种形态的表单输入项所组成,当我们有了 Ant Design/Fusion Next 之后,我们可以轻松做到不需要关心表单输入项内部的复杂交互逻辑了,只需要关注如何组装表单页面即可,这就是组件化所带来的强大赋能。 可是,表单除了表单输入项,其实还有各种数据关联,逻辑联动,校验联动,这些可是实实在在的业务层,如何在这一层里更进一步提效? -同时,因为我们使用的是React技术栈,那我们又该如何解决表单项数量无限增加的交互操作性能问题? +同时,因为我们使用的是 React 技术栈,那我们又该如何解决表单项数量无限增加的交互操作性能问题? 还有,我们的表单能不能通过简单配置即可快速生产表单,即便非技术人员也能快速高效的开发出复杂表单页面? - - **总而言之,怎么更好的管理表单逻辑,怎么保证表单性能,怎么让非技术人员高效开发表单页面这就是我们一直所面临的问题。** - - ## Formily -Formily解决方案的本质是构造了一个Observable Form Graph,在这个Form Graph中,我们抽象了整个表单领域模型,同时这个模型又是一个无限循环状态机。 +Formily 解决方案的本质是构造了一个 Observable Form Graph,在这个 Form Graph 中,我们抽象了整个表单领域模型,同时这个模型又是一个无限循环状态机。 ![](https://img.alicdn.com/tfs/TB1cdP2fUT1gK0jSZFrXXcNCXXa-1112-718.png) -这个状态机主要有3个特点: +这个状态机主要有 3 个特点: - 无限循环 - 分布式管理状态 -- UI无关 +- UI 无关 在这样一个状态机下,我们就能很简单的来描述字段间的联动关系。我们甚至可以用一句极简表达式来描述: @@ -66,27 +56,23 @@ setFieldState( - 通过一个选择器来选择字段,同时任何联动都是从表单生命周期而发起 - 联动的最终操作是操作具体字段的状态,可以是值,可以是它的显示隐藏,也可以是具体组件属性等等。 -所以,Formily借助这样一个内核,我们轻松的实现了: +所以,Formily 借助这样一个内核,我们轻松的实现了: - 在复杂联动场景下更加清晰简单的描述联动的方式 - 在超多表单项场景下可以获得更好的表单操作性能 - 在跨终端场景下实现通用表单解决方案 - - ## 核心特性 -在上面有讲到,Formily的状态机模型,当然,Formily不止这些,我们在上层又抽象了几层 +在上面有讲到,Formily 的状态机模型,当然,Formily 不止这些,我们在上层又抽象了几层 -- UI桥接层(React/Vue/Angualr/小程序....),这一层主要是对接各种组件化框架,对不同体系的用户提供更便捷的表单管理方案 +- UI 桥接层(React/Vue/Angualr/小程序....),这一层主要是对接各种组件化框架,对不同体系的用户提供更便捷的表单管理方案 -- Schema动态渲染层(React/Vue/Angular/小程序...),这一层主要提供了针对Schema场景下的各种上层能力,比如典型的协议化联动,协议化布局能力 +- Schema 动态渲染层(React/Vue/Angular/小程序...),这一层主要提供了针对 Schema 场景下的各种上层能力,比如典型的协议化联动,协议化布局能力 -- Schema编辑器层,这一层主要提供了可视化配置Schema能力,方便非技术人员快速配置表单 +- Schema 编辑器层,这一层主要提供了可视化配置 Schema 能力,方便非技术人员快速配置表单 -- 研发工具层,这一层主要提供了针对Formily的开发者调试能力 - - +- 研发工具层,这一层主要提供了针对 Formily 的开发者调试能力 ## 整体架构 @@ -94,9 +80,7 @@ setFieldState( 从以上架构中,我们可以看到 -整个Formily是由一个UI无关的内核所驱动的,这样的好处就是,我们的表单方案,是可以轻松做到跨终端的,同时,在上层,我们拥有一份标准的表单协议,可以做表单动态渲染,所以,我们可以想象一下,**一份JSON Schema驱动多端的表单页面动态渲染** 这样的目标,是可以轻松实现的,这样对于整个前端表单研发领域,是一个突破性的解决方案。 - - +整个 Formily 是由一个 UI 无关的内核所驱动的,这样的好处就是,我们的表单方案,是可以轻松做到跨终端的,同时,在上层,我们拥有一份标准的表单协议,可以做表单动态渲染,所以,我们可以想象一下,**一份 JSON Schema 驱动多端的表单页面动态渲染** 这样的目标,是可以轻松实现的,这样对于整个前端表单研发领域,是一个突破性的解决方案。 ## 数据公示 @@ -131,26 +115,23 @@ NPM Downloads(Formily):![](https://img.shields.io/npm/dy/@formily/core) - 钉钉 - 天猫超市、天猫国际、阿里健康、农村淘宝、淘宝心选 - - ## 未来规划 -- 支持更多端,现在主要支持了React,Rax,未来会考虑支持小程序 -- 支持更多组件体系,比如Antd Mobile、Material Design等 -- 支持更完备,可实际用在生产环境中的的Schema表单配置器 +- 支持更多端,现在主要支持了 React,Rax,未来会考虑支持小程序 +- 支持更多组件体系,比如 Antd Mobile、Material Design 等 +- 支持更完备,可实际用在生产环境中的的 Schema 表单配置器 - 在集团内部落地更多场景 ## 对社区的期望 -我们希望社区更多的参与进来共建,如果觉得文档不完善,可以参与完善文档,如果觉得代码有问题,可以提PR修复 -如果希望我们能支持更多场景,也可以提Feature Request +我们希望社区更多的参与进来共建,如果觉得文档不完善,可以参与完善文档,如果觉得代码有问题,可以提 PR 修复 +如果希望我们能支持更多场景,也可以提 Feature Request 我们的知识是从社区而来,我们也有必要赋能社区,帮助社区更好的运作下去。 - ## 团队介绍 -Formily属于集团中后台开箱即用战役中的核心子项目 +Formily 属于集团中后台开箱即用战役中的核心子项目 项目组长:元彦,大果 diff --git a/docs/zh-cn/jsx-develop/complex-linkage.md b/docs/zh-cn/jsx-develop/complex-linkage.md index 7418393525b..eddbfcfc4b9 100644 --- a/docs/zh-cn/jsx-develop/complex-linkage.md +++ b/docs/zh-cn/jsx-develop/complex-linkage.md @@ -569,13 +569,11 @@ const useAsyncLinkageEffect = () => { linkage.value('bb', '1111') }, 1000) }) - merge(onFieldValueChange$('bb'), onFieldInit$('bb')).subscribe( - fieldState => { - if (!fieldState.value) return linkage.hide('cc') - linkage.show('cc') - linkage.value('cc', fieldState.value) - } - ) + merge(onFieldValueChange$('bb'), onFieldInit$('bb')).subscribe(fieldState => { + if (!fieldState.value) return linkage.hide('cc') + linkage.show('cc') + linkage.value('cc', fieldState.value) + }) } const App = () => ( @@ -679,7 +677,11 @@ const App = () => { initialValue={true} component={Select} /> - + ) })} diff --git a/docs/zh-cn/jsx-develop/faq.md b/docs/zh-cn/jsx-develop/faq.md index 2552ffe91b5..94ac93f1692 100644 --- a/docs/zh-cn/jsx-develop/faq.md +++ b/docs/zh-cn/jsx-develop/faq.md @@ -1,62 +1,62 @@ # FAQ ```jsx -import React, { useEffect, useState } from "react"; -import ReactDOM from "react-dom"; -import { SchemaForm } from "@formily/antd"; // 或者 @formily/next -import { Input, Select, Radio } from "@formily/antd-components"; -import Printer from "@formily/printer"; -import "antd/dist/antd.css"; +import React, { useEffect, useState } from 'react' +import ReactDOM from 'react-dom' +import { SchemaForm } from '@formily/antd' // 或者 @formily/next +import { Input, Select, Radio } from '@formily/antd-components' +import Printer from '@formily/printer' +import 'antd/dist/antd.css' const mockSchema = { - type: "object", + type: 'object', properties: { aa: { - type: "boolean", + type: 'boolean', enum: [ - { label: "设置bb的枚举列表", value: true }, - { label: "还原bb的枚举列表", value: false } + { label: '设置bb的枚举列表', value: true }, + { label: '还原bb的枚举列表', value: false } ], default: false, - title: "AA", - "x-component": "RadioGroup", - "x-linkages": [ + title: 'AA', + 'x-component': 'RadioGroup', + 'x-linkages': [ { - type: "value:schema", - target: "bb", - condition: "{{!!$value}}", + type: 'value:schema', + target: 'bb', + condition: '{{!!$value}}', schema: { - enum: ["xx1", "xx2", "xx3"] + enum: ['xx1', 'xx2', 'xx3'] }, otherwise: { - enum: ["zz"] + enum: ['zz'] } } ] }, bb: { - type: "string", - title: "BB", - "x-component": "Input", - enum: ["yy"] + type: 'string', + title: 'BB', + 'x-component': 'Input', + enum: ['yy'] }, cc: { - type: "string", - title: "{{customCCTitle}}", - "x-component": "Input" + type: 'string', + title: '{{customCCTitle}}', + 'x-component': 'Input' } } -}; +} const App = () => { const [schema, setSchema] = useState({ - type: "object" - }); + type: 'object' + }) useEffect(() => { setTimeout(() => { - setSchema(mockSchema); - }, 1000); - }, []); + setSchema(mockSchema) + }, 1000) + }, []) return ( @@ -64,17 +64,16 @@ const App = () => { schema={schema} components={{ Input, Select, RadioGroup: Radio.Group }} onSubmit={values => { - console.log(values); + console.log(values) }} expressionScope={{ - customTitle: "this is custom title", - customCCTitle: "CC" + customTitle: 'this is custom title', + customCCTitle: 'CC' }} /> - ); -}; + ) +} -ReactDOM.render(, document.getElementById("root")); - -``` \ No newline at end of file +ReactDOM.render(, document.getElementById('root')) +``` diff --git a/docs/zh-cn/jsx-develop/form-path.md b/docs/zh-cn/jsx-develop/form-path.md index 7667250f33b..0573f4a7695 100644 --- a/docs/zh-cn/jsx-develop/form-path.md +++ b/docs/zh-cn/jsx-develop/form-path.md @@ -168,9 +168,9 @@ const App = () => { - - - ) - })} - - ) - }} - + return ( + + + {({ state, mutators }) => { + const onAdd = () => mutators.push() + return ( +
+ {state.value.map((item, index) => { + const onRemove = index => mutators.remove(index) + const onMoveUp = index => mutators.moveUp(index) + const onMoveDown = index => mutators.moveDown(index) + return ( +
+ + + + + +
+ ) + })} + +
+ ) + }} +
+ ) } ``` @@ -45,9 +59,9 @@ import { Button } from 'antd' import styled from 'styled-components' import { Form, FormItem, InternalFieldList as FieldList } from '@formily/antd' import { Input } from '@formily/antd-components' -import'antd/dist/antd.css' +import 'antd/dist/antd.css' -const RowStyleLayout = styled((props) =>
)` +const RowStyleLayout = styled(props =>
)` .ant-btn { margin-right: 16px; } @@ -61,52 +75,73 @@ const RowStyleLayout = styled((props) =>
)` const App = () => { return (
- - {({ state, mutators }) => { - const onAdd = () => mutators.push() - return (
- {state.value.map((item, index) => { - const onRemove = (index) => mutators.remove(index) - const onMoveUp = (index) => mutators.moveUp(index) - const onMoveDown = (index) => mutators.moveDown(index) - return ( - - - - - - ) - })} - -
) - }} -
+ + {({ state, mutators }) => { + const onAdd = () => mutators.push() + return ( +
+ {state.value.map((item, index) => { + const onRemove = index => mutators.remove(index) + const onMoveUp = index => mutators.moveUp(index) + const onMoveDown = index => mutators.moveDown(index) + return ( + + + + + + + + ) + })} + +
+ ) + }} +
) } ReactDOM.render(, document.getElementById('root')) - ``` -### 使用useFormEffects实现局部联动 +### 使用 useFormEffects 实现局部联动 ```jsx import React from 'react' import ReactDOM from 'react-dom' import { Button } from 'antd' import styled from 'styled-components' -import { Form, FormItem, InternalFieldList as FieldList, FormPath, - VirtualField, useFormEffects, FormEffectHooks } from '@formily/antd' +import { + Form, + FormItem, + InternalFieldList as FieldList, + FormPath, + VirtualField, + useFormEffects, + FormEffectHooks +} from '@formily/antd' import { Input, Radio } from '@formily/antd-components' -import'antd/dist/antd.css' +import 'antd/dist/antd.css' const { onFieldValueChange$ } = FormEffectHooks -const RowStyleLayout = styled((props) =>
)` +const RowStyleLayout = styled(props =>
)` .ant-btn { margin-right: 16px; } @@ -117,74 +152,90 @@ const RowStyleLayout = styled((props) =>
)` } ` -const ReuseLogic = (props) => { - useFormEffects(($, { setFieldState }) => { - setFieldState('array.*.visible', state => { - state.value = state.value === undefined ? false : state.value - }) - onFieldValueChange$('array.*.visible').subscribe(fieldState => { - setFieldState(FormPath.transform(fieldState.name, /\d/, $1 => `array.${$1}.bb`), state => { - state.visible = fieldState.value === true - }) - }) +const ReuseLogic = props => { + useFormEffects(($, { setFieldState }) => { + setFieldState('array.*.visible', state => { + state.value = state.value === undefined ? false : state.value + }) + onFieldValueChange$('array.*.visible').subscribe(fieldState => { + setFieldState( + FormPath.transform(fieldState.name, /\d/, $1 => `array.${$1}.bb`), + state => { + state.visible = fieldState.value === true + } + ) }) + }) - return {props.children} + return {props.children} } const App = () => { return (
- - - {({ state, mutators }) => { - const onAdd = () => mutators.push() - return (
- {state.value.map((item, index) => { - const onRemove = (index) => mutators.remove(index) - const onMoveUp = (index) => mutators.moveUp(index) - const onMoveDown = (index) => mutators.moveDown(index) - return ( - - - - ) - })} - -
) - }} -
-
+ + + {({ state, mutators }) => { + const onAdd = () => mutators.push() + return ( +
+ {state.value.map((item, index) => { + const onRemove = index => mutators.remove(index) + const onMoveUp = index => mutators.moveUp(index) + const onMoveDown = index => mutators.moveDown(index) + return ( + + + + + + ) + })} + +
+ ) + }} +
+
) } ReactDOM.render(, document.getElementById('root')) - ``` ### IMutators -| 属性名 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| change | 改变当前行的值 | change(...values: any[]): any | | -| focus | 聚焦 | | | -| blur | 失焦 | | | -| push | 增加一行数据 | (value?: any): any[] | | -| pop | 弹出最后一行 | change(...values: any[]): any | | -| insert | 插入一行数据 | (index: number, value: any): any[] | | -| remove | 删除某一行 | (index: number | string): any | | -| unshift | 插入第一行数据 | (value: any): any[] | | -| shift | 删除第一行是数据 | (): any[] | | -| exist | 是否存在某一行 | (index?: number | string): boolean | | -| move | 将指定行数据移动到某一行 | ($from: number, $to: number): any[] | | -| moveDown | 将某一行往下移 | (index: number): any[] | | -| moveUp | 将某一行往上移 | (index: number): any[] | | -| validate | 执行校验 | (opts?: IFormExtendedValidateFieldOptions): Promise | | - +| 属性名 | 说明 | 类型 | 默认值 | +| :------- | :----------------------- | :----------------------------------------------------------------------- | :--------------- | +| change | 改变当前行的值 | change(...values: any[]): any | | +| focus | 聚焦 | | | +| blur | 失焦 | | | +| push | 增加一行数据 | (value?: any): any[] | | +| pop | 弹出最后一行 | change(...values: any[]): any | | +| insert | 插入一行数据 | (index: number, value: any): any[] | | +| remove | 删除某一行 | (index: number | string): any | | +| unshift | 插入第一行数据 | (value: any): any[] | | +| shift | 删除第一行是数据 | (): any[] | | +| exist | 是否存在某一行 | (index?: number | string): boolean | | +| move | 将指定行数据移动到某一行 | ($from: number, $to: number): any[] | | +| moveDown | 将某一行往下移 | (index: number): any[] | | +| moveUp | 将某一行往上移 | (index: number): any[] | | +| validate | 执行校验 | (opts?: IFormExtendedValidateFieldOptions): Promise | | diff --git a/docs/zh-cn/other-links.md b/docs/zh-cn/other-links.md index d57fae61a8b..27b4f0aa3e5 100644 --- a/docs/zh-cn/other-links.md +++ b/docs/zh-cn/other-links.md @@ -3,4 +3,4 @@ - [知乎专栏](https://zhuanlan.zhihu.com/uform) - [GITHUB](https://github.com/alibaba/formily) - [UForm v0](https://uformjs.org) -- [UForm v1](https://uform-next.netlify.com) \ No newline at end of file +- [UForm v1](https://uform-next.netlify.com) diff --git a/docs/zh-cn/schema-develop/actions-effects.md b/docs/zh-cn/schema-develop/actions-effects.md index a6d754040b7..bf9d19db017 100644 --- a/docs/zh-cn/schema-develop/actions-effects.md +++ b/docs/zh-cn/schema-develop/actions-effects.md @@ -55,9 +55,9 @@ ReactDOM.render(, document.getElementById('root')) **案例解析** -- 借助actions,我们可以在外部自由调用FormAPI -- 注意:调用actions中的API,必须要Form初始化完成才能调用,其实我们真实业务逻辑通常也是会在某个异步事件完成后调用,所以对这个初始化时机问题感知不多,如果需要保证调用安全性,我们可以调用createAsyncFormActions来创建actions,但是所创建出来的actions的内部所有API,调用时都会返回Promise对象 +- 借助 actions,我们可以在外部自由调用 FormAPI +- 注意:调用 actions 中的 API,必须要 Form 初始化完成才能调用,其实我们真实业务逻辑通常也是会在某个异步事件完成后调用,所以对这个初始化时机问题感知不多,如果需要保证调用安全性,我们可以调用 createAsyncFormActions 来创建 actions,但是所创建出来的 actions 的内部所有 API,调用时都会返回 Promise 对象 ## 如何监听 Form 内部事件 -这部分,已经在生命周期章节中有详细讲解 \ No newline at end of file +这部分,已经在生命周期章节中有详细讲解 diff --git a/docs/zh-cn/schema-develop/complex-linkage.md b/docs/zh-cn/schema-develop/complex-linkage.md index 74556a79563..7814db865cb 100644 --- a/docs/zh-cn/schema-develop/complex-linkage.md +++ b/docs/zh-cn/schema-develop/complex-linkage.md @@ -1060,5 +1060,5 @@ ReactDOM.render(, document.getElementById('root')) **案例解析** - 主联动逻辑是一对多联动 -- 借助FormSpy可以针对具体字段做监听,所以可以很方便的做UI联动状态同步 -- 借助FormActions可以方便的在外部操作Form内部状态 \ No newline at end of file +- 借助 FormSpy 可以针对具体字段做监听,所以可以很方便的做 UI 联动状态同步 +- 借助 FormActions 可以方便的在外部操作 Form 内部状态 diff --git a/docs/zh-cn/schema-develop/complext-self-inc-component.md b/docs/zh-cn/schema-develop/complext-self-inc-component.md index faa5c5e202d..a30b604b435 100644 --- a/docs/zh-cn/schema-develop/complext-self-inc-component.md +++ b/docs/zh-cn/schema-develop/complext-self-inc-component.md @@ -4,7 +4,7 @@ ### 基础使用 -**Formily** 内置 **ArrayCards**, **ArrayTable** 作为官方自增列表组件,两者使用方式完全一致,主要差异在UI上。下面用 **ArrayTable** 举例(**ArrayCards**同理), 代码如下: +**Formily** 内置 **ArrayCards**, **ArrayTable** 作为官方自增列表组件,两者使用方式完全一致,主要差异在 UI 上。下面用 **ArrayTable** 举例(**ArrayCards**同理), 代码如下: ```tsx import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' @@ -12,26 +12,26 @@ import { Input, ArrayTable } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => ( - - - - - - - - + + + + + + + + ) ``` ### ArrayTable 和 ArrayCards -底层均是基于 [ArrayList](https://github.com/alibaba/formily/blob/master/packages/react-shared-components/src/ArrayList.tsx) 的,不过承载的容器组件分别是 **Table** 和 **Card**, DEMO如下: +底层均是基于 [ArrayList](https://github.com/alibaba/formily/blob/master/packages/react-shared-components/src/ArrayList.tsx) 的,不过承载的容器组件分别是 **Table** 和 **Card**, DEMO 如下: ```jsx import React, { useState } from 'react' @@ -39,42 +39,42 @@ import ReactDOM from 'react-dom' import { Button } from 'antd' import { Schema, SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Input, ArrayTable, ArrayCards } from '@formily/antd-components' -import'antd/dist/antd.css' +import 'antd/dist/antd.css' const App = () => { return ( - - - - - + + + + - - - - - - + + + + + + + ) } @@ -84,15 +84,14 @@ ReactDOM.render(, document.getElementById('root')) ### 如何定制按钮及操作渲染 -| 属性名 | 说明 | 类型 | -|:----------|:---------------------------------|:--------------------| -| renderAddition | 自定义添加按钮内容 | () => React.ReactElement | -| renderRemove | 自定义删除按钮内容 | (index: Number) => React.ReactElement | -| renderMoveDown | 自定义向下移动按钮内容 | (index: Number) => React.ReactElement | -| renderMoveUp | 自定义向上移动按钮内容 | (index: Number) => React.ReactElement | -| renderEmpty | 自定义渲染空数据内容 | (index: Number) => React.ReactElement | -| renderExtraOperations | 自定义渲染额外操作按钮内容 | (index: Number) => React.ReactElement | - +| 属性名 | 说明 | 类型 | +| :-------------------- | :------------------------- | :------------------------------------ | +| renderAddition | 自定义添加按钮内容 | () => React.ReactElement | +| renderRemove | 自定义删除按钮内容 | (index: Number) => React.ReactElement | +| renderMoveDown | 自定义向下移动按钮内容 | (index: Number) => React.ReactElement | +| renderMoveUp | 自定义向上移动按钮内容 | (index: Number) => React.ReactElement | +| renderEmpty | 自定义渲染空数据内容 | (index: Number) => React.ReactElement | +| renderExtraOperations | 自定义渲染额外操作按钮内容 | (index: Number) => React.ReactElement | 通过以上属性可以复写并自定义操作按钮,以下会演示几个常见场景。 @@ -105,57 +104,65 @@ import React from 'react' import ReactDOM from 'react-dom' import { Button } from 'antd' import styled from 'styled-components' -import { FormSpy, createFormActions, SchemaForm, SchemaField, SchemaMarkupField as Field } from '@formily/antd' +import { + FormSpy, + createFormActions, + SchemaForm, + SchemaField, + SchemaMarkupField as Field +} from '@formily/antd' import { Input, ArrayCards } from '@formily/antd-components' -import'antd/dist/antd.css' +import 'antd/dist/antd.css' const actions = createFormActions() const App = () => { return ( - null, - renderMoveUp: () => null, - renderAddition: () => '+add', - renderRemove: (idx) => { - return - {({ state }) => state.value === 'morally' ? null : 'remove'} + null, + renderMoveUp: () => null, + renderAddition: () => '+add', + renderRemove: idx => { + return ( + + {({ state }) => (state.value === 'morally' ? null : 'remove')} - } - }} - > - - - - + ) + } + }} + > + + + + ) } ReactDOM.render(, document.getElementById('root')) - ``` - -### ArrayTable专属定制属性 +### ArrayTable 专属定制属性 除了上述属性外,**ArrayTable** 还支持以下属性 -| 属性名 | 说明 | 类型 | -|:----------|:---------------------------------|:--------------------| -| operations | 为false时不展示操作列,作为Table.Column的props传入 | { [key: string]: any } `or` false | -| operationsWidth | 操作列宽度 | number | -| draggable | 是否启用拖拽模式 | boolean | +| 属性名 | 说明 | 类型 | +| :-------------- | :------------------------------------------------------- | :-------------------------------- | +| operations | 为 false 时不展示操作列,作为 Table.Column 的 props 传入 | { [key: string]: any } `or` false | +| operationsWidth | 操作列宽度 | number | +| draggable | 是否启用拖拽模式 | boolean | 下面例子来展示下如何使用上述属性 @@ -164,73 +171,80 @@ import React from 'react' import ReactDOM from 'react-dom' import { Button } from 'antd' import styled from 'styled-components' -import { FormSpy, createFormActions, SchemaForm, SchemaField, SchemaMarkupField as Field } from '@formily/antd' +import { + FormSpy, + createFormActions, + SchemaForm, + SchemaField, + SchemaMarkupField as Field +} from '@formily/antd' import { Input, ArrayTable } from '@formily/antd-components' -import'antd/dist/antd.css' +import 'antd/dist/antd.css' const actions = createFormActions() const App = () => { return ( - - - - - + + + + + ) } ReactDOM.render(, document.getElementById('root')) - ``` ## 拓展定制专属自增列表 ### 简单版本 -这个版本旨在快速讲清楚如何实现自增组件,仅需要 **25** 行代码就能实现一个 `Formily` 自增组件。可以点击 [IMutators](#IMutators) 了解更多API。 +这个版本旨在快速讲清楚如何实现自增组件,仅需要 **25** 行代码就能实现一个 `Formily` 自增组件。可以点击 [IMutators](#IMutators) 了解更多 API。 ```tsx import { Button } from 'antd' import { SchemaForm, SchemaField, toArr, FormPath } from '@formily/antd' -const ArrayCustom = (props) => { - const { value, schema, className, editable, path, mutators } = props; - const componentProps = schema.getExtendsComponentProps() || {} - const onAdd = () => mutators.push(schema.items.getEmptyValue()) - const onRemove = (index) => mutators.remove(index) - const onMoveUp = (index) => mutators.moveUp(index) - const onMoveDown = (index) => mutators.moveDown(index) - - return
- {toArr(value).map((item, index) => ( -
- - - - -
- ))} - +const ArrayCustom = props => { + const { value, schema, className, editable, path, mutators } = props + const componentProps = schema.getExtendsComponentProps() || {} + const onAdd = () => mutators.push(schema.items.getEmptyValue()) + const onRemove = index => mutators.remove(index) + const onMoveUp = index => mutators.moveUp(index) + const onMoveDown = index => mutators.moveDown(index) + + return ( +
+ {toArr(value).map((item, index) => ( +
+ + + + +
+ ))} +
+ ) } ArrayCustom.isFieldComponent = true ``` @@ -243,25 +257,26 @@ ArrayCustom.isFieldComponent = true ```tsx +const ArrayCustom = props => { + const { value, className, editable, path, mutators } = props + const [dynamicSchema, setDynamicSchema] = useState(null) + const loadDynamicSchema = () => { + setDynamicSchema( + new Schema({ + type: 'object', + properties: { + dy1: { + title: '动态字段1', + 'x-component': 'Input', + 'x-component-props': { placeholder: 'input' } + }, + dy2: { + title: '动态字段2', + 'x-component': 'Input', + 'x-component-props': { placeholder: 'input' } + } + } + }) + ) + } + + return ( + + {toArr(value).map((item, index) => ( + + #{index + 1}. + + + ))} + + ) } ArrayCustom.isFieldComponent = true @@ -538,21 +592,21 @@ ArrayCustom.isFieldComponent = true const App = () => { return ( - - - - - + + + + + ) } @@ -560,25 +614,23 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - ## Interface ### IMutators -| 属性名 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| change | 改变当前行的值 | change(...values: any[]): any | | -| focus | 聚焦 | | | -| blur | 失焦 | | | -| push | 增加一行数据 | (value?: any): any[] | | -| pop | 弹出最后一行 | change(...values: any[]): any | | -| insert | 插入一行数据 | (index: number, value: any): any[] | | -| remove | 删除某一行 | (index: number | string): any | | -| unshift | 插入第一行数据 | (value: any): any[] | | -| shift | 删除第一行是数据 | (): any[] | | -| exist | 是否存在某一行 | (index?: number | string): boolean | | -| move | 将指定行数据移动到某一行 | ($from: number, $to: number): any[] | | -| moveDown | 将某一行往下移 | (index: number): any[] | | -| moveUp | 将某一行往上移 | (index: number): any[] | | -| validate | 执行校验 | (opts?: IFormExtendedValidateFieldOptions): Promise | | - +| 属性名 | 说明 | 类型 | 默认值 | +| :------- | :----------------------- | :----------------------------------------------------------------------- | :--------------- | +| change | 改变当前行的值 | change(...values: any[]): any | | +| focus | 聚焦 | | | +| blur | 失焦 | | | +| push | 增加一行数据 | (value?: any): any[] | | +| pop | 弹出最后一行 | change(...values: any[]): any | | +| insert | 插入一行数据 | (index: number, value: any): any[] | | +| remove | 删除某一行 | (index: number | string): any | | +| unshift | 插入第一行数据 | (value: any): any[] | | +| shift | 删除第一行是数据 | (): any[] | | +| exist | 是否存在某一行 | (index?: number | string): boolean | | +| move | 将指定行数据移动到某一行 | ($from: number, $to: number): any[] | | +| moveDown | 将某一行往下移 | (index: number): any[] | | +| moveUp | 将某一行往上移 | (index: number): any[] | | +| validate | 执行校验 | (opts?: IFormExtendedValidateFieldOptions): Promise | | diff --git a/docs/zh-cn/schema-develop/create-complex-field-component.md b/docs/zh-cn/schema-develop/create-complex-field-component.md index ad00ff19d05..19ba186cce9 100644 --- a/docs/zh-cn/schema-develop/create-complex-field-component.md +++ b/docs/zh-cn/schema-develop/create-complex-field-component.md @@ -251,4 +251,4 @@ ReactDOM.render(, document.getElementById('root')) - useFormEffects 中写的联动,是具有全局效果的,所以,你完全可以在 A 组件内部隐式的控制 B、C、D...组件的联动,这样在一定程度上是可以提高开发效率,但是也容易埋坑,如果一个项目是多人协作,对方是完全不知道你的组件到底做了什么,所以,我们要尽可能的做到,在 useFormEffects 内写的联动逻辑,只是与组件内部字段相关的,同时要多关注,组件内部和外部是否存在联动冲突问题 - FormItem 组件,name 属性必须传完整路径,因为 FormItem 组件与 SchemaForm 是共享上下文的,所以可以享受到 labelCol/wraperCol 的批量控制效果 -- 注意,用于递归渲染的SchemaField组件必须要传schema对象,否则会存在子字段读取schema失效的风险问题。 \ No newline at end of file +- 注意,用于递归渲染的 SchemaField 组件必须要传 schema 对象,否则会存在子字段读取 schema 失效的风险问题。 diff --git a/docs/zh-cn/schema-develop/form-extension.md b/docs/zh-cn/schema-develop/form-extension.md index 25d3767da11..eab6af0be27 100644 --- a/docs/zh-cn/schema-develop/form-extension.md +++ b/docs/zh-cn/schema-develop/form-extension.md @@ -170,9 +170,9 @@ ReactDOM.render(, document.getElementById('root')) 扩展 Schema Field 组件可以说是我们平时用的最多的扩展方案,主要是用于扩展具体字段 UI 组件,目前我们提供的扩展方式主要有: - SchemaForm 中传入 components 扩展(要求组件满足 value/onChange API) -- SchemaForm 中传入 components 组件拥有isFieldComponent静态属性,可以拿到FieldProps -- registerFormField 全局注册扩展组件,要求传入组件名和具体组件,同时,如果针对满足 value/onChange 的组件,需要用 connect 包装,不包装,需要手动同步状态(借助mutators) -- registerFormFields 全局批量注册扩展组件,同时,如果针对满足 value/onChange 的组件,需要用 connect 包装,不包装,需要手动同步状态(借助mutators) +- SchemaForm 中传入 components 组件拥有 isFieldComponent 静态属性,可以拿到 FieldProps +- registerFormField 全局注册扩展组件,要求传入组件名和具体组件,同时,如果针对满足 value/onChange 的组件,需要用 connect 包装,不包装,需要手动同步状态(借助 mutators) +- registerFormFields 全局批量注册扩展组件,同时,如果针对满足 value/onChange 的组件,需要用 connect 包装,不包装,需要手动同步状态(借助 mutators) **components 实例扩展** @@ -191,7 +191,7 @@ const CustomComponent = props => { ) } -const CustomFieldComponent = props=>{ +const CustomFieldComponent = props => { return ( { const [value, setValue] = useState({}) return ( { setValue(values) }} diff --git a/docs/zh-cn/schema-develop/form-graph.md b/docs/zh-cn/schema-develop/form-graph.md index 23d64306a10..51eee85d3d5 100644 --- a/docs/zh-cn/schema-develop/form-graph.md +++ b/docs/zh-cn/schema-develop/form-graph.md @@ -271,4 +271,4 @@ ReactDOM.render(, document.getElementById('root')) **案例解析** - 调用 actions.getFormGraph()可以直接查看实时表单状态树 -- 节点状态树中是有可能存在ReactNode,所以JSON.stringify打印的时候需要先将ReactNode转换一下,否则会报循环引用错误 \ No newline at end of file +- 节点状态树中是有可能存在 ReactNode,所以 JSON.stringify 打印的时候需要先将 ReactNode 转换一下,否则会报循环引用错误 diff --git a/docs/zh-cn/schema-develop/form-path.md b/docs/zh-cn/schema-develop/form-path.md index c67edc6ade4..29a4b01b74b 100644 --- a/docs/zh-cn/schema-develop/form-path.md +++ b/docs/zh-cn/schema-develop/form-path.md @@ -97,7 +97,7 @@ import { Reset } from '@formily/antd' // 或者 @formily/next import { ArrayTable, Input } from '@formily/antd-components' -import {Button} from 'antd' +import { Button } from 'antd' import Printer from '@formily/printer' import 'antd/dist/antd.css' @@ -144,10 +144,14 @@ const App = () => { - + @@ -159,7 +163,7 @@ ReactDOM.render(, document.getElementById('root')) **案例解析** -- 在 ` onFieldValueChange$ `入参中使用\*批量匹配数组第 n 项的 aa 字段 +- 在 `onFieldValueChange$`入参中使用\*批量匹配数组第 n 项的 aa 字段 - 使用 FormPath.transform 将一个路径转换成另外一个路径,目前该例子主要用于转换成相邻路径 ## 使用路径匹配能力批量操作字段状态 diff --git a/docs/zh-cn/schema-develop/form-schema.md b/docs/zh-cn/schema-develop/form-schema.md index 728249e4358..a0dd4764dbd 100644 --- a/docs/zh-cn/schema-develop/form-schema.md +++ b/docs/zh-cn/schema-develop/form-schema.md @@ -226,7 +226,7 @@ Formily 针对 Form Schema 支持了表达式的能力,可以帮助我们在 J ``` -> 注意:如果不指定condition,那么默认会执行state(value:state)/schema(value:schema)流程 +> 注意:如果不指定 condition,那么默认会执行 state(value:state)/schema(value:schema)流程 ### 扩展联动协议 diff --git a/docs/zh-cn/schema-develop/form-value.md b/docs/zh-cn/schema-develop/form-value.md index e11458a49fc..39a651084d4 100644 --- a/docs/zh-cn/schema-develop/form-value.md +++ b/docs/zh-cn/schema-develop/form-value.md @@ -109,7 +109,6 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - # InitialValues 属性使用场景 ```jsx @@ -165,6 +164,6 @@ ReactDOM.render(, document.getElementById('root')) - 点击刷新只会针对未设置默认值字段生效,且只生效一次 - 点击重置不会置空数据 -- 先点击刷新,后点击重置,点击刷新的时候,initialValues受表单重渲染而重新更新,aa字段的初始值更新了,但是因为aa当前是有值状态,所以不会被默认值更新所影响 -- 先点击刷新,后点击重置,点击重置按钮的时候,默认是会将值变为初始值,因为初始值变了,所以aa字段的值也变了,如果不希望出现这种行为,可以给重置按钮配置强制清空 -- 交替点击清空和刷新按钮,可以重复赋值,是因为初始值一直在变,清空使得字段又恢复到无默认值状态,所以是可以持续赋值的,看着就像前面value的效果一样 \ No newline at end of file +- 先点击刷新,后点击重置,点击刷新的时候,initialValues 受表单重渲染而重新更新,aa 字段的初始值更新了,但是因为 aa 当前是有值状态,所以不会被默认值更新所影响 +- 先点击刷新,后点击重置,点击重置按钮的时候,默认是会将值变为初始值,因为初始值变了,所以 aa 字段的值也变了,如果不希望出现这种行为,可以给重置按钮配置强制清空 +- 交替点击清空和刷新按钮,可以重复赋值,是因为初始值一直在变,清空使得字段又恢复到无默认值状态,所以是可以持续赋值的,看着就像前面 value 的效果一样 diff --git a/docs/zh-cn/schema-develop/introduction.md b/docs/zh-cn/schema-develop/introduction.md index 5dd1eb03a08..a9970d271f4 100644 --- a/docs/zh-cn/schema-develop/introduction.md +++ b/docs/zh-cn/schema-develop/introduction.md @@ -9,7 +9,7 @@ - 纯 JSX(源码) 开发表单 - 该方案主要用于纯前端开发方式,或者在前两个方案的自定义组件内部的开发以复合形态来开发。 -下面我们以具体例子来详细介绍不同开发模式的差异,案例右下角可以查看源码也可以跳转至 codesandbox 中试玩该例子。 +下面我们以具体例子来详细介绍不同开发模式的差异,案例右下角可以查看源码也可以跳转至 CodeSandbox 中试玩该例子。 我们在看例子的过程中不需要详细理解具体 API,只需要了解个大概即可。 ## JSON Schema 开发表单 @@ -32,9 +32,9 @@ const App = () => { onSubmit={console.log} schema={{ type: 'object', - "x-component-props":{ - labelCol:7, - wrapperCol:12 + 'x-component-props': { + labelCol: 7, + wrapperCol: 12 }, properties: { string: { diff --git a/docs/zh-cn/schema-develop/lifecycle.md b/docs/zh-cn/schema-develop/lifecycle.md index ce742c921b4..3a72d68a5de 100644 --- a/docs/zh-cn/schema-develop/lifecycle.md +++ b/docs/zh-cn/schema-develop/lifecycle.md @@ -16,38 +16,38 @@ ## 类型列举 -| 常量名 | 常量值 | 描述 | Hook | 返回值 | -| ------------------------------- | ----------------------------- | ------------------------------------------------ | ----------------------------- | ---------- | -| ON_FORM_WILL_INIT | "onFormWillInit" | 表单初始化前触发 | ` onFormWillInit$ ` | FormState | -| ON_FORM_INIT | "onFormInit" | 表单初始化之后触发 | ` onFormInit$ ` | FormState | -| ON_FORM_CHANGE | "onFormChange" | 表单状态变化时触发 | ` onFormChange$ ` | FormState | -| ON_FORM_MOUNT | "onFormMount" | 表单组件挂载完毕时触发 | ` onFormMount$ ` | FormState | -| ON_FORM_UNMOUNT | "onFormUnmount" | 表单组件卸载时触发 | ` onFormUnmount$ ` | FormState | -| ON_FORM_SUBMIT | "onFormSubmit" | 表单提交时触发 | ` onFormSubmit$ ` | FormState | -| ON_FORM_RESET | "onFormReset" | 表单重置时触发 | ` onFormReset$ ` | FormState | -| ON_FORM_SUBMIT_START | "onFormSubmitStart" | 表单提交开始时触发 | ` onFormSubmitStart$ ` | FormState | -| ON_FORM_SUBMIT_END | "onFormSubmitEnd" | 表单提交完成时触发 | ` onFormSubmitEnd$ ` | FormState | -| ON_FORM_SUBMIT_VALIDATE_START | "onFormSubmitValidateStart" | 表单提交校验开始时触发 | ` onFormSubmitValidateStart$ ` | FormState | -| ON_FORM_SUBMIT_VALIDATE_SUCCESS | "onFormSubmitValidateSuccess" | 表单提交校验成功时触发 | ` onFormSubmitValidateSuccess$ ` | FormState | -| ON_FORM_SUBMIT_VALIDATE_FAILED | "onFormSubmitValidateFailed" | 表单提交校验失败时触发 | ` onFormSubmitValidateFailed$ ` | FormState | -| ON_FORM_ON_SUBMIT_SUCCESS | "onFormOnSubmitSuccess" | 表单自定义onSubmit成功,入参为onSubmit返回值 | ` onFormOnSubmitSuccess$ ` | any | -| ON_FORM_ON_SUBMIT_FAILED | "onFormOnSubmitFailed" | 表单自定义onSubmit失败,入参为onSubmit抛出异常 | ` onFormOnSubmitFailed$ ` | Error | -| ON_FORM_VALUES_CHANGE | "onFormValuesChange" | 表单值变化时触发 | ` onFormValuesChange$ ` | FormState | -| ON_FORM_INITIAL_VALUES_CHANGE | "onFormInitialValuesChange" | 表单初始值变化时触发 | ` onFormInitialValuesChange$ ` | FormState | -| ON_FORM_VALIDATE_START | "onFormValidateStart" | 表单校验开始时触发 | ` onFormValidateStart$ ` | FormState | -| ON_FORM_VALIDATE_END | "onFormValidateEnd" | 表单校验结束时触发 | ` onFormValidateEnd$ ` | FormState | -| ON_FORM_INPUT_CHANGE | "onFormInputChange" | 表单输入事件触发时触发(人为操作,不包含间接联动) | ` onFormInputChange$ ` | FormState | -| ON_FORM_GRAPH_CHANGE | "onFormGraphChange" | 表单树结构变化时触发 | ` onFormGraphChange$ ` | FormGraph | -| ON_FIELD_WILL_INIT | "onFieldWillInit" | 字段初始化前触发 | ` onFieldWillInit$ ` | FieldState | -| ON_FIELD_INIT | "onFieldInit" | 字段初始化时触发 | ` onFieldInit$ ` | FieldState | -| ON_FIELD_CHANGE | "onFieldChange" | 字段状态发生变化时触发 | ` onFieldChange$ ` | FieldState | -| ON_FIELD_INPUT_CHANGE | "onFieldInputChange" | 字段输入事件触发时触发(人为操作,不包含间接联动) | ` onFieldInputChange$ ` | FieldState | -| ON_FIELD_VALUE_CHANGE | "onFieldValueChange" | 字段值变化时触发 | ` onFieldValueChange$ ` | FieldState | -| ON_FIELD_INITIAL_VALUE_CHANGE | "onFieldInitialValueChange" | 字段初始值变化时触发 | ` onFieldInitialValueChange$ ` | FieldState | -| ON_FIELD_VALIDATE_START | "onFieldValidateStart" | 字段校验开始时触发 | ` onFieldValidateStart$ ` | FieldState | -| ON_FIELD_VALIDATE_END | "onFieldValidateEnd" | 字段校验结束时触发 | ` onFieldValidateEnd$ ` | FieldState | -| ON_FIELD_MOUNT | "onFieldMount" | 字段挂载时触发 | ` onFieldMount$ ` | FieldState | -| ON_FIELD_UNMOUNT | "onFieldUnmount" | 字段卸载时触发 | ` onFieldUnmount$ ` | FieldState | +| 常量名 | 常量值 | 描述 | Hook | 返回值 | +| ------------------------------- | ----------------------------- | -------------------------------------------------- | ------------------------------ | ---------- | +| ON_FORM_WILL_INIT | "onFormWillInit" | 表单初始化前触发 | `onFormWillInit$` | FormState | +| ON_FORM_INIT | "onFormInit" | 表单初始化之后触发 | `onFormInit$` | FormState | +| ON_FORM_CHANGE | "onFormChange" | 表单状态变化时触发 | `onFormChange$` | FormState | +| ON_FORM_MOUNT | "onFormMount" | 表单组件挂载完毕时触发 | `onFormMount$` | FormState | +| ON_FORM_UNMOUNT | "onFormUnmount" | 表单组件卸载时触发 | `onFormUnmount$` | FormState | +| ON_FORM_SUBMIT | "onFormSubmit" | 表单提交时触发 | `onFormSubmit$` | FormState | +| ON_FORM_RESET | "onFormReset" | 表单重置时触发 | `onFormReset$` | FormState | +| ON_FORM_SUBMIT_START | "onFormSubmitStart" | 表单提交开始时触发 | `onFormSubmitStart$` | FormState | +| ON_FORM_SUBMIT_END | "onFormSubmitEnd" | 表单提交完成时触发 | `onFormSubmitEnd$` | FormState | +| ON_FORM_SUBMIT_VALIDATE_START | "onFormSubmitValidateStart" | 表单提交校验开始时触发 | `onFormSubmitValidateStart$` | FormState | +| ON_FORM_SUBMIT_VALIDATE_SUCCESS | "onFormSubmitValidateSuccess" | 表单提交校验成功时触发 | `onFormSubmitValidateSuccess$` | FormState | +| ON_FORM_SUBMIT_VALIDATE_FAILED | "onFormSubmitValidateFailed" | 表单提交校验失败时触发 | `onFormSubmitValidateFailed$` | FormState | +| ON_FORM_ON_SUBMIT_SUCCESS | "onFormOnSubmitSuccess" | 表单自定义 onSubmit 成功,入参为 onSubmit 返回值 | `onFormOnSubmitSuccess$` | any | +| ON_FORM_ON_SUBMIT_FAILED | "onFormOnSubmitFailed" | 表单自定义 onSubmit 失败,入参为 onSubmit 抛出异常 | `onFormOnSubmitFailed$` | Error | +| ON_FORM_VALUES_CHANGE | "onFormValuesChange" | 表单值变化时触发 | `onFormValuesChange$` | FormState | +| ON_FORM_INITIAL_VALUES_CHANGE | "onFormInitialValuesChange" | 表单初始值变化时触发 | `onFormInitialValuesChange$` | FormState | +| ON_FORM_VALIDATE_START | "onFormValidateStart" | 表单校验开始时触发 | `onFormValidateStart$` | FormState | +| ON_FORM_VALIDATE_END | "onFormValidateEnd" | 表单校验结束时触发 | `onFormValidateEnd$` | FormState | +| ON_FORM_INPUT_CHANGE | "onFormInputChange" | 表单输入事件触发时触发(人为操作,不包含间接联动) | `onFormInputChange$` | FormState | +| ON_FORM_GRAPH_CHANGE | "onFormGraphChange" | 表单树结构变化时触发 | `onFormGraphChange$` | FormGraph | +| ON_FIELD_WILL_INIT | "onFieldWillInit" | 字段初始化前触发 | `onFieldWillInit$` | FieldState | +| ON_FIELD_INIT | "onFieldInit" | 字段初始化时触发 | `onFieldInit$` | FieldState | +| ON_FIELD_CHANGE | "onFieldChange" | 字段状态发生变化时触发 | `onFieldChange$` | FieldState | +| ON_FIELD_INPUT_CHANGE | "onFieldInputChange" | 字段输入事件触发时触发(人为操作,不包含间接联动) | `onFieldInputChange$` | FieldState | +| ON_FIELD_VALUE_CHANGE | "onFieldValueChange" | 字段值变化时触发 | `onFieldValueChange$` | FieldState | +| ON_FIELD_INITIAL_VALUE_CHANGE | "onFieldInitialValueChange" | 字段初始值变化时触发 | `onFieldInitialValueChange$` | FieldState | +| ON_FIELD_VALIDATE_START | "onFieldValidateStart" | 字段校验开始时触发 | `onFieldValidateStart$` | FieldState | +| ON_FIELD_VALIDATE_END | "onFieldValidateEnd" | 字段校验结束时触发 | `onFieldValidateEnd$` | FieldState | +| ON_FIELD_MOUNT | "onFieldMount" | 字段挂载时触发 | `onFieldMount$` | FieldState | +| ON_FIELD_UNMOUNT | "onFieldUnmount" | 字段卸载时触发 | `onFieldUnmount$` | FieldState | ## 引入生命周期 @@ -130,7 +130,7 @@ ReactDOM.render(, document.getElementById('root')) **案例解析** -- 在 effects 中使用$订阅生命周期 +- 在 effects 中使用\$订阅生命周期 - 通过订阅 ON_FORM_INIT 在表单初始化时设置字段状态 - 通过订阅 ON_FIELD_VALUE_CHANGE 在字段值变化时设置字段状态 @@ -374,7 +374,8 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` + **案例解析** -- 自定义组件内部使用useFormEffects可以订阅表单生命周期,需要注意一个地方,在useFormEffects内部无法监听onFormInit事件,因为组件渲染到自定义组件的时候,其实表单已经初始化,所以,如果我们需要做一些初始化操作,只需要在useFormEffects入参回调函数内直接写即可,这样代表当前自定义组件初始化时执行。 -- 自定义组件内部可以使用纯源码开发模式,使用FormItem组件 \ No newline at end of file +- 自定义组件内部使用 useFormEffects 可以订阅表单生命周期,需要注意一个地方,在 useFormEffects 内部无法监听 onFormInit 事件,因为组件渲染到自定义组件的时候,其实表单已经初始化,所以,如果我们需要做一些初始化操作,只需要在 useFormEffects 入参回调函数内直接写即可,这样代表当前自定义组件初始化时执行。 +- 自定义组件内部可以使用纯源码开发模式,使用 FormItem 组件 diff --git a/docs/zh-cn/schema-develop/manage-business.md b/docs/zh-cn/schema-develop/manage-business.md index 3cdf02df5e2..822aa2c1953 100644 --- a/docs/zh-cn/schema-develop/manage-business.md +++ b/docs/zh-cn/schema-develop/manage-business.md @@ -112,7 +112,7 @@ export const useBusinessEffects = context => { } ``` -③:引入createEffects +③:引入 createEffects ```tsx // src/effects/index.ts @@ -124,7 +124,7 @@ export const createEffects = context => () => { } ``` -④:传入createEffects +④:传入 createEffects ```tsx // src/index.tsx @@ -152,7 +152,7 @@ export const App = () => { #### 表单初始化默认值 -①:定义React Hook +①:定义 React Hook ```tsx // src/hooks/useInitialValues.ts @@ -171,7 +171,7 @@ export const useInitialValues = () => { } ``` -②:引入React Hook +②:引入 React Hook ```tsx // src/index.tsx @@ -193,7 +193,7 @@ export const App = () => { #### 异步下拉选项 -①:定义EffectHook +①:定义 EffectHook ```tsx // src/effects/useAsyncDataSource.ts @@ -222,7 +222,7 @@ const useAsyncDataSource = (name, service) => { } ``` -②:引入EffectHook +②:引入 EffectHook ```tsx // src/effects/index.ts @@ -247,7 +247,7 @@ export const createEffects = context => () => { #### 可搜索的异步下拉选项 -①:定义EffectHook +①:定义 EffectHook ```tsx // src/effects/useAsyncSearchDataSource.ts @@ -281,7 +281,7 @@ const useSearchDataSource = (name, service) => { } ``` -②:引入EffectHook +②:引入 EffectHook ```tsx // src/effects/index.ts @@ -312,11 +312,11 @@ export const createEffects = context => ($) => { } }) }) - + $('requestAsyncDataSource','aaa.bbb').subscribe(()=>{ //监听aaa.ccc的下拉选项查询结果 }) - + $('requestSearchDataSource','aaa.ccc').subscribe(()=>{ //监听aaa.ccc的搜索结果,考虑一种场景,我们需要在搜索的过程实时联动 }) @@ -337,11 +337,9 @@ export const createEffects = context => ($) => { // src/extensions/MyComponent.tsx import { connect } from '@formily/antd' -export const MyComponent = connect()( - ({value,onChange})=>{ - //内部接收value,调用onChange - } -) +export const MyComponent = connect()(({ value, onChange }) => { + //内部接收value,调用onChange +}) ``` ②:引入扩展组件 @@ -358,38 +356,37 @@ import { MyComponent } from './extentions/MyComponent' export const App = () => { const initialValues = useInitialValues() return ( - + }} + initialValues={initialValues} + effects={createEffects()} + > ) } ``` - - ## 批处理字段 -**方法**:借助FormPath能力,对所有字段进行批处理 +**方法**:借助 FormPath 能力,对所有字段进行批处理 **优点**:大大提高开发效率 -① :定义EffectHook +① :定义 EffectHook ```tsx // src/effects/useAsyncSearchDataSource.ts import { createFormActions, FormEffectHooks } from '@formily/antd' const { onFormInit$ } = FormEffectHooks -const useBatchLocales = (locales) => { +const useBatchLocales = locales => { const { dispatch, setFieldState } = createFormActions() onFormInit$().subscribe(() => { setFieldState('*', state => { - if(state.name && locales[state.name]){ + if (state.name && locales[state.name]) { state.props.title = locales[state.name] } }) @@ -397,7 +394,7 @@ const useBatchLocales = (locales) => { } ``` -②:引入EffectHook +②:引入 EffectHook ```tsx // src/effects/index.ts @@ -430,11 +427,11 @@ export const createEffects = context => ($) => { } }) }) - + $('requestAsyncDataSource','aaa.bbb').subscribe(()=>{ //监听aaa.ccc的下拉选项查询结果 }) - + $('requestSearchDataSource','aaa.ccc').subscribe(()=>{ //监听aaa.ccc的搜索结果,考虑一种场景,我们需要在搜索的过程实时联动 }) @@ -451,7 +448,7 @@ export { } ``` -④:引入国际化文案,并传入createEffects +④:引入国际化文案,并传入 createEffects ```tsx // src/index.tsx @@ -466,22 +463,21 @@ import zhCN from './local/zh-cn' export const App = () => { const initialValues = useInitialValues() return ( - + locale: zhCN + })} + > ) } ``` - - ## 整体目录结构 - src @@ -502,8 +498,6 @@ export const App = () => { - Index.ts - Index.tsx - - ## 总结 -整体来看,我们这样一层层的将项目分解了之后,后续的整体维护性就会大大提高,当然你们还可以根据自己业务的特殊性来做一些定制。 \ No newline at end of file +整体来看,我们这样一层层的将项目分解了之后,后续的整体维护性就会大大提高,当然你们还可以根据自己业务的特殊性来做一些定制。 diff --git a/docs/zh-cn/uform-upgrade.md b/docs/zh-cn/uform-upgrade.md index d5dd516acbe..c7ec32666da 100644 --- a/docs/zh-cn/uform-upgrade.md +++ b/docs/zh-cn/uform-upgrade.md @@ -24,7 +24,6 @@ import React from 'react' import { SchemaForm, Field } from '@uform/antd' import 'antd/dist/antd.css' - const App = () => { return ( diff --git a/package.json b/package.json index 378598526a7..a022b7f7e75 100644 --- a/package.json +++ b/package.json @@ -153,6 +153,10 @@ "scripts/**.@(ts|tsx|js)": [ "npm run lint", "git add" + ], + "**/*.md": [ + "prettier --write", + "git add" ] }, "collective": { diff --git a/packages/antd-components/README.zh-cn.md b/packages/antd-components/README.zh-cn.md index 2f446587385..379d2dcc89a 100644 --- a/packages/antd-components/README.zh-cn.md +++ b/packages/antd-components/README.zh-cn.md @@ -8,27 +8,25 @@ npm install --save @formily/antd-components ### 显式加载组件 -通过在``传入components,可以快速置入组件,表单字段通过`x-component`使用到内置的组件。 +通过在``传入 components,可以快速置入组件,表单字段通过`x-component`使用到内置的组件。 ```tsx -import { SchemaForm, SchemaMarkupField as Field, FormButtonGroup, Submit } from '@formily/antd' +import { + SchemaForm, + SchemaMarkupField as Field, + FormButtonGroup, + Submit +} from '@formily/antd' import { Input } from '@formily/antd-components' import 'antd/dist/antd.css' export default () => { return ( - - + + ) } - ``` ### 使用内置组件 @@ -36,7 +34,12 @@ export default () => { 通过 `setup` 方法,可以快速置入内置的表单组件,免去维护全局`components`的工作。 ```tsx -import { SchemaForm, SchemaMarkupField as Field, FormButtonGroup, Submit } from '@formily/antd' +import { + SchemaForm, + SchemaMarkupField as Field, + FormButtonGroup, + Submit +} from '@formily/antd' import { setup } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -44,15 +47,10 @@ setup() export default () => { return ( - + ) } - ``` ### 内置组件类型 @@ -82,18 +80,14 @@ export default () => { | object | | 嵌套表单 | 自动连接路径信息 | | array | [ArrayCards](#ArrayCards)(默认) | 表单数组 | - #### Input -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Input } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -101,7 +95,7 @@ const App = () => { return ( { 'x-component': 'Input', 'x-component-props': { placeholder: 'input' - }, - }, + } + } } }} - > - - + > ) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -132,7 +124,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Input } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -141,7 +133,7 @@ const App = () => { return ( { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - Form, - FormItem, -} from '@formily/antd' +import { Form, FormItem } from '@formily/antd' import { Input } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -185,15 +174,12 @@ ReactDOM.render(, document.getElementById('root')) #### Select -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Select } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -201,7 +187,7 @@ const App = () => { return ( { 'x-component': 'Select', 'x-component-props': { placeholder: 'select' - }, + } }, objSelect: { title: 'Object Select', @@ -225,20 +211,18 @@ const App = () => { ], 'x-component-props': { placeholder: 'select' - }, - }, + } + } } }} - > - - + > ) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -246,7 +230,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Select } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -255,7 +239,7 @@ const App = () => { return ( { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - Form, - FormItem, -} from '@formily/antd' +import { Form, FormItem } from '@formily/antd' import { Select } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return (
- - { ReactDOM.render(, document.getElementById('root')) ``` - #### TextArea -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Input } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -352,20 +335,18 @@ const App = () => { 'x-component': 'TextArea', 'x-component-props': { placeholder: 'textarea' - }, - }, + } + } } }} - > - - + > ) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -373,16 +354,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Input } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -408,9 +387,11 @@ import { Input } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return ( - - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -418,15 +399,12 @@ ReactDOM.render(, document.getElementById('root')) #### Password -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Password } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -444,20 +422,18 @@ const App = () => { 'x-component': 'Password', 'x-component-props': { placeholder: 'Password' - }, - }, + } + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -465,16 +441,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Password } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -500,9 +474,11 @@ import { Password } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -510,15 +486,12 @@ ReactDOM.render(, document.getElementById('root')) #### NumberPicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { NumberPicker } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -533,20 +506,18 @@ const App = () => { properties: { textarea: { title: 'NumberPicker', - 'x-component': 'NumberPicker', - }, + 'x-component': 'NumberPicker' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -554,16 +525,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { NumberPicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -586,26 +555,28 @@ import { NumberPicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) ``` - #### Switch -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Switch } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -620,20 +591,18 @@ const App = () => { properties: { textarea: { title: 'Switch', - 'x-component': 'Switch', - }, + 'x-component': 'Switch' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -641,21 +610,15 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Switch } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - - + + ) } @@ -663,7 +626,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -673,9 +636,11 @@ import { Switch } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -683,15 +648,12 @@ ReactDOM.render(, document.getElementById('root')) #### DatePicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -709,20 +671,18 @@ const App = () => { 'x-component': 'DatePicker', 'x-component-props': { format: 'YYYY-MM-DD HH:mm:ss' - }, - }, + } + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -730,16 +690,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -765,9 +723,16 @@ import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -775,7 +740,7 @@ ReactDOM.render(, document.getElementById('root')) #### RangePicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' @@ -783,7 +748,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -799,20 +764,18 @@ const App = () => { properties: { '[start,end]': { title: 'RangePicker', - 'x-component': 'RangePicker', - }, + 'x-component': 'RangePicker' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -820,21 +783,15 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - - + + ) } @@ -842,7 +799,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -852,9 +809,15 @@ import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -862,15 +825,12 @@ ReactDOM.render(, document.getElementById('root')) #### WeekPicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -885,20 +845,18 @@ const App = () => { properties: { textarea: { title: 'WeekPicker', - 'x-component': 'WeekPicker', - }, + 'x-component': 'WeekPicker' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -906,21 +864,15 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - - + + ) } @@ -928,7 +880,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -938,9 +890,15 @@ import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -948,15 +906,12 @@ ReactDOM.render(, document.getElementById('root')) #### MonthPicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -971,20 +926,18 @@ const App = () => { properties: { textarea: { title: 'MonthPicker', - 'x-component': 'MonthPicker', - }, + 'x-component': 'MonthPicker' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -992,21 +945,15 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - - + + ) } @@ -1014,7 +961,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1024,9 +971,15 @@ import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1034,15 +987,12 @@ ReactDOM.render(, document.getElementById('root')) #### YearPicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1057,20 +1007,18 @@ const App = () => { properties: { textarea: { title: 'YearPicker', - 'x-component': 'YearPicker', - }, + 'x-component': 'YearPicker' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1078,21 +1026,15 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - - + + ) } @@ -1100,7 +1042,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1110,9 +1052,15 @@ import { DatePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1120,15 +1068,12 @@ ReactDOM.render(, document.getElementById('root')) #### TimePicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { TimePicker } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1146,20 +1091,18 @@ const App = () => { 'x-component': 'TimePicker', 'x-component-props': { format: 'YYYY-MM-DD HH:mm:ss' - }, - }, + } + } } }} - > - -
+ > ) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1167,16 +1110,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { TimePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1202,9 +1143,16 @@ import { TimePicker } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1212,15 +1160,12 @@ ReactDOM.render(, document.getElementById('root')) #### Range -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Range } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1241,19 +1186,17 @@ const App = () => { max: 1024, marks: [0, 1024] } - }, + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1261,16 +1204,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Range } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1298,14 +1239,18 @@ import { Range } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1313,15 +1258,12 @@ ReactDOM.render(, document.getElementById('root')) #### Upload -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Upload } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1354,19 +1296,17 @@ const App = () => { 'x-component-props': { listType: 'text' } - }, + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1374,16 +1314,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Upload } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1425,20 +1363,28 @@ import { Upload } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - - - ) + return ( +
+ + + + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1446,15 +1392,12 @@ ReactDOM.render(, document.getElementById('root')) #### Checkbox -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Checkbox } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1463,7 +1406,7 @@ const App = () => { { { label: 'Three', value: '3' }, { label: 'Four', value: '4' } ] - }, + } } }} - > - - + >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1502,7 +1443,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Checkbox } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1512,7 +1453,7 @@ const App = () => { { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1549,21 +1490,27 @@ import { Checkbox } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - + + - ) + /> + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1571,15 +1518,12 @@ ReactDOM.render(, document.getElementById('root')) #### Radio -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Radio } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1588,7 +1532,7 @@ const App = () => { { { label: 'Three', value: '3' }, { label: 'Four', value: '4' } ] - }, + } } }} - > - - + >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1627,7 +1569,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Radio } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1637,7 +1579,7 @@ const App = () => { { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1674,21 +1616,27 @@ import { Radio } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - + + - ) + /> + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1696,15 +1644,12 @@ ReactDOM.render(, document.getElementById('root')) #### Rating -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Rating } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1723,19 +1668,17 @@ const App = () => { 'x-component-props': { allowHalf: true } - }, + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1743,7 +1686,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Rating } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1770,7 +1713,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1780,12 +1723,11 @@ import { Rating } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1793,15 +1735,12 @@ ReactDOM.render(, document.getElementById('root')) #### Transfer -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/antd' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/antd' import { Transfer } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1827,19 +1766,17 @@ const App = () => { showSearch: true, render: record => record.label } - }, + } } }} - > - - + > ) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1847,7 +1784,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/antd' import { Transfer } from '@formily/antd-components' import 'antd/dist/antd.css' @@ -1881,7 +1818,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1891,19 +1828,23 @@ import { Transfer } from '@formily/antd-components' import 'antd/dist/antd.css' const App = () => { - return (
- record.label} - showSearch - /> - ) + return ( +
+ record.label} + showSearch + /> + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1918,11 +1859,12 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, - Field, +import { + SchemaForm, + Field, FormButtonGroup, Submit, - Reset, + Reset } from '@formily/antd' import { Input, @@ -1930,7 +1872,8 @@ import { DatePicker, FormBlock, FormItemGrid, - FormLayout } from '@formily/antd-components' + FormLayout +} from '@formily/antd-components' import 'antd/dist/antd.css' import Printer from '@formily/printer' @@ -1940,7 +1883,7 @@ const App = () => ( components={{ Input, ArrayCards, - RangePicker: DatePicker.RangePicker, + RangePicker: DatePicker.RangePicker }} > , document.getElementById('root')) ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, - Field, +import { + SchemaForm, + Field, FormButtonGroup, Submit, - Reset, + Reset } from '@formily/antd' import { Input, @@ -2020,7 +1964,8 @@ import { DatePicker, FormBlock, FormItemGrid, - FormLayout } from '@formily/antd-components' + FormLayout +} from '@formily/antd-components' import 'antd/dist/antd.css' import Printer from '@formily/printer' @@ -2030,7 +1975,7 @@ const App = () => ( components={{ ArrayTable, Input, - RangePicker: DatePicker.RangePicker, + RangePicker: DatePicker.RangePicker }} > @@ -2072,11 +2017,10 @@ ReactDOM.render(, document.getElementById('root')) ### Layout Components - #### FormCard > FormCard 组件 Props, 完全继承自 [CardProps](#CardProps)。 -> FormCard与[FormBlock](#FormBlock) 唯一区别是样式上是否有框 +> FormCard 与[FormBlock](#FormBlock) 唯一区别是样式上是否有框 **用法** @@ -2124,20 +2068,19 @@ ReactDOM.render(, document.getElementById('root')) > FormStep 组件 Props -* IFormStep - -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| dataSource | 分步配置 | StepItemProps[] | | -| current | 当前步骤 | number | | -| direction | 展示方向 | 'horizontal' `or` 'vertical' | | -| labelPlacement | 横向布局时的内容排列 | 'horizontal' `or` 'vertical' | | -| status | 状态 | 'wait' `or` 'process' `or` 'finish' `or` 'error' | | -| size | 指定大小,目前支持普通(default)和迷你(small) | 'default' `or` 'small' | | -| onChange | 点击切换步骤时触发 | (current: number) => void | | -| progressDot | 点状步骤条,可以设置为一个 function,labelPlacement 将强制为 vertical | boolean | Function | | -| initial | 起始序号,从 0 开始记数 | number | 0 | +- IFormStep +| 参数 | 说明 | 类型 | 默认值 | +| :------------- | :-------------------------------------------------------------------- | :----------------------------------------------- | :------- | +| dataSource | 分步配置 | StepItemProps[] | | +| current | 当前步骤 | number | | +| direction | 展示方向 | 'horizontal' `or` 'vertical' | | +| labelPlacement | 横向布局时的内容排列 | 'horizontal' `or` 'vertical' | | +| status | 状态 | 'wait' `or` 'process' `or` 'finish' `or` 'error' | | +| size | 指定大小,目前支持普通(default)和迷你(small) | 'default' `or` 'small' | | +| onChange | 点击切换步骤时触发 | (current: number) => void | | +| progressDot | 点状步骤条,可以设置为一个 function,labelPlacement 将强制为 vertical | boolean | Function | | +| initial | 起始序号,从 0 开始记数 | number | 0 | **用法** @@ -2153,7 +2096,7 @@ import { createFormActions, Reset } from '@formily/antd' -import { +import { Input, FormGridRow, FormItemGrid, @@ -2240,7 +2183,6 @@ export default () => ( ) ``` - #### FormTab ```jsx @@ -2312,11 +2254,15 @@ const App = () => ( - + - - - ) - })} - -
) - }} - + + {({ state, mutators }) => { + const onAdd = () => mutators.push() + return ( +
+ {state.value.map((item, index) => { + const onRemove = index => mutators.remove(index) + const onMoveUp = index => mutators.moveUp(index) + const onMoveDown = index => mutators.moveDown(index) + return ( + + + + + + + + ) + })} + +
+ ) + }} +
) } @@ -491,17 +518,17 @@ ReactDOM.render(, document.getElementById('root')) #### `` -* IFormButtonGroupProps +- IFormButtonGroupProps -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| sticky |是否吸附在页面底部 | boolean | | -| itemStyle |每个Btn的样式 | React.CSSProperties | | -| align |对齐方式 | 'left' `or` 'right' `or` 'start' `or` 'end' `or` 'top' `or` 'bottom' `or` 'center' | | -| triggerDistance | 按钮间距离 | number | | -| zIndex | z-index | number | | -| span | 跨列配置 | number | string | | -| offset | 偏移配置 | number | string | | +| 参数 | 说明 | 类型 | 默认值 | +| :-------------- | :----------------- | :--------------------------------------------------------------------------------- | :----- | +| sticky | 是否吸附在页面底部 | boolean | | +| itemStyle | 每个 Btn 的样式 | React.CSSProperties | | +| align | 对齐方式 | 'left' `or` 'right' `or` 'start' `or` 'end' `or` 'top' `or` 'bottom' `or` 'center' | | +| triggerDistance | 按钮间距离 | number | | +| zIndex | z-index | number | | +| span | 跨列配置 | number | string | | +| offset | 偏移配置 | number | string | | **用法** @@ -515,7 +542,7 @@ import { FormButtonGroup, Reset } from '@formily/antd' -import { +import { setup, FormItemGrid, FormCard, @@ -524,7 +551,7 @@ import { } from '@formily/antd-components' import { Button } from 'antd' import Printer from '@formily/printer' -import'antd/dist/antd.css' +import 'antd/dist/antd.css' setup() const App = () => { @@ -554,13 +581,12 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - ### Hook #### `useFormTableQuery` -* 调用 useFormTableQuery 会返回 Table 和 Form 属性,只需简单传递给对应组件即可 -* useFormTableQuery 的传入参数是一个返回 Promise 对象的函数,该函数约定了它的出入参形式,如果接口请求出入参不符合这个约定,需要手动转换。 +- 调用 useFormTableQuery 会返回 Table 和 Form 属性,只需简单传递给对应组件即可 +- useFormTableQuery 的传入参数是一个返回 Promise 对象的函数,该函数约定了它的出入参形式,如果接口请求出入参不符合这个约定,需要手动转换。 ```typescript const useFormTableQuery = ( @@ -569,20 +595,20 @@ const useFormTableQuery = ( ) ``` -* useFormTableQuery入参 +- useFormTableQuery 入参 -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| 参数1 |列表请求服务 | (payload: [IQueryParams](#IQueryParams)) => [IQueryResponse](#IQueryParams) | Promise<[IQueryResponse](#IQueryParams)> | | -| 参数2 |请求处理middlewares | IEffectMiddleware<[ISchemaFormActions](#IFormActions)> | | +| 参数 | 说明 | 类型 | 默认值 | +| :----- | :------------------- | :-------------------------------------------------------------------------- | :--------------------------------------- | +| 参数 1 | 列表请求服务 | (payload: [IQueryParams](#IQueryParams)) => [IQueryResponse](#IQueryParams) | Promise<[IQueryResponse](#IQueryParams)> | | +| 参数 2 | 请求处理 middlewares | IEffectMiddleware<[ISchemaFormActions](#IFormActions)> | | -* useFormTableQuery返回结果 +- useFormTableQuery 返回结果 -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| trigger |触发列表请求 | any | | -| form | Form属性,主要为effects | { effects: [IFormEffect](#IFormEffect) } | | -| table |Table属性 | { loading:boolean, dataSource: any[], pagination: [Pagination](#Pagination), onChange } | | +| 参数 | 说明 | 类型 | 默认值 | +| :------ | :------------------------ | :-------------------------------------------------------------------------------------- | :----- | +| trigger | 触发列表请求 | any | | +| form | Form 属性,主要为 effects | { effects: [IFormEffect](#IFormEffect) } | | +| table | Table 属性 | { loading:boolean, dataSource: any[], pagination: [Pagination](#Pagination), onChange } | | **用法** @@ -645,7 +671,6 @@ const columns = [ } ] - const App = () => { const { form, table } = useFormTableQuery(service) return ( @@ -678,8 +703,8 @@ ReactDOM.render(, document.getElementById('root')) 通过使用 `useFormEffects` 可以轻松实现拥有局部逻辑表单。 -* 使用 useFormEffects 可以实现局部effect的表单组件,效果同:[简单联动](#简单联动) -* 注意:监听的生命周期是从 `ON_FORM_MOUNT` 开始 +- 使用 useFormEffects 可以实现局部 effect 的表单组件,效果同:[简单联动](#简单联动) +- 注意:监听的生命周期是从 `ON_FORM_MOUNT` 开始 **签名** @@ -708,45 +733,47 @@ import { setup } from '@formily/antd-components' setup() const actions = createFormActions() -const FragmentContainer = createVirtualBox('ffb', (props) => { +const FragmentContainer = createVirtualBox('ffb', props => { useFormEffects(($, { setFieldState }) => { $(LifeCycleTypes.ON_FORM_MOUNT).subscribe(() => { - setFieldState('a~', state => state.visible = false) + setFieldState('a~', state => (state.visible = false)) }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((triggerState) => { - setFieldState('a~', state => { - state.visible = triggerState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe( + triggerState => { + setFieldState('a~', state => { + state.visible = triggerState.value + }) + } + ) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe((fieldState) => { + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe(fieldState => { setFieldState('a-copy', state => { state.value = fieldState.value }) }) }) - return ( - - {props.children} - - ) -}); - + return {props.children} +}) // 具有局部逻辑的表单 const FormFragment = () => { - return - - - - + return ( + + + + + + ) } const App = () => { @@ -762,7 +789,7 @@ ReactDOM.render(, document.getElementById('root')) #### `useFormState` -使用 useFormState 为自定义组件提供FormState扩展和管理能力 +使用 useFormState 为自定义组件提供 FormState 扩展和管理能力 **签名** @@ -788,16 +815,22 @@ import { setup } from '@formily/antd-components' setup() const actions = createFormActions() -const FormFragment = createVirtualBox('fusestatform', (props) => { +const FormFragment = createVirtualBox('fusestatform', props => { const [formState, setFormState] = useFormState({ extendVar: 0 }) const { extendVar } = formState - return
- -
count: {extendVar}
-
+ return ( +
+ +
count: {extendVar}
+
+ ) }) const App = () => { @@ -828,26 +861,28 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, +import { + SchemaForm, SchemaMarkupField as Field, - createFormActions, createEffectHook, - useForm, + createFormActions, + createEffectHook, + useForm, useFormEffects, useFieldState, LifeCycleTypes, - createControllerBox, + createControllerBox } from '@formily/antd' import { setup } from '@formily/antd-components' setup() const changeTab$ = createEffectHook('changeTab') const actions = createFormActions() -const TabFragment = (props) => { - const [fieldState, setLocalFieldState ] = useFieldState({ current: 0 }) +const TabFragment = props => { + const [fieldState, setLocalFieldState] = useFieldState({ current: 0 }) const { current } = fieldState const { children, dataSource, form } = props - const update = (cur) => { + const update = cur => { form.notify('changeTab', cur) setLocalFieldState({ current: cur @@ -861,37 +896,47 @@ const TabFragment = (props) => { }) }) - changeTab$().subscribe((idx) => { + changeTab$().subscribe(idx => { dataSource.forEach((item, itemIdx) => { - setFieldState(item.name, state => { - state.display = itemIdx === idx + setFieldState(item.name, state => { + state.display = itemIdx === idx + }) }) }) - }) }) const btns = dataSource.map((item, idx) => { - const focusStyle = idx === current ? { color: '#fff', background: 'blue' } : {} - return + const focusStyle = + idx === current ? { color: '#fff', background: 'blue' } : {} + return ( + + ) }) return btns } -const FormTab = createControllerBox('formTab', (props) => { - const { form, props: comProps } = props; +const FormTab = createControllerBox('formTab', props => { + const { form, props: comProps } = props return }) const App = () => { return ( - +
@@ -905,8 +950,8 @@ ReactDOM.render(, document.getElementById('root')) #### useForm -* 创建一个 [IForm](#IForm) 实例。需要注意的是,该操作会代理整个表单创建过程,包括actions的处理。 -* useForm是底层方法,它在包装具有业务属性的表单框架时非常有用。 +- 创建一个 [IForm](#IForm) 实例。需要注意的是,该操作会代理整个表单创建过程,包括 actions 的处理。 +- useForm 是底层方法,它在包装具有业务属性的表单框架时非常有用。 **签名** @@ -926,15 +971,17 @@ type useForm = < ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, +import { + SchemaForm, SchemaMarkupField as Field, - createFormActions, createEffectHook, - useForm, + createFormActions, + createEffectHook, + useForm, FormSpy, useFormEffects, useFieldState, LifeCycleTypes, - createVirtualBox, + createVirtualBox } from '@formily/antd' import { setup } from '@formily/antd-components' @@ -943,7 +990,7 @@ const actions = createFormActions() const App = () => { const form = useForm({ value: { username: 'moe' }, - actions, + actions }) return ( @@ -954,7 +1001,6 @@ const App = () => { } ReactDOM.render(, document.getElementById('root')) - ``` #### useField @@ -972,30 +1018,29 @@ type useField = (options: IFieldStateUIProps): IFieldHook ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, +import { + SchemaForm, SchemaMarkupField as Field, - createFormActions, createEffectHook, - useForm, + createFormActions, + createEffectHook, + useForm, FormSpy, useFormEffects, LifeCycleTypes, createControllerBox, - useField, + useField } from '@formily/antd' -const CustomField = createControllerBox('customField', (props) => { - const { name } = props; - const realName = props.props['x-component-props']['x-name']; - const { - form, - state, - props: fieldProps, - mutators - } = useField({ - name: `${name}.${realName}`, - }) - - return +const CustomField = createControllerBox('customField', props => { + const { name } = props + const realName = props.props['x-component-props']['x-name'] + const { form, state, props: fieldProps, mutators } = useField({ + name: `${name}.${realName}` + }) + + return ( + + ) }) const App = () => { @@ -1003,14 +1048,15 @@ const App = () => { - {({ state, form }) =>
name: {form && form.getFieldValue('username')}
} + {({ state, form }) => ( +
name: {form && form.getFieldValue('username')}
+ )}
) } ReactDOM.render(, document.getElementById('root')) - ``` #### useVirtualField @@ -1028,21 +1074,23 @@ type UseVirtualField = (options: IVirtualFieldStateProps): IVirtualFieldHook ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, +import { + SchemaForm, SchemaMarkupField as Field, - createFormActions, createEffectHook, - useForm, + createFormActions, + createEffectHook, + useForm, FormSpy, useFormEffects, LifeCycleTypes, createControllerBox, - useVirtualField, + useVirtualField } from '@formily/antd' import { setup } from '@formily/antd-components' setup() -const LayoutBox = createControllerBox('LayoutBox', (props) => { +const LayoutBox = createControllerBox('LayoutBox', props => { useVirtualField({ name: 'random' }) return
{props.children}
}) @@ -1053,13 +1101,12 @@ const App = () => { - + ) } ReactDOM.render(, document.getElementById('root')) - ``` #### useFormSpy @@ -1077,21 +1124,23 @@ type useFormSpy = (props: IFormSpyProps): ISpyHook ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, +import { + SchemaForm, SchemaMarkupField as Field, - createFormActions, createEffectHook, - useForm, + createFormActions, + createEffectHook, + useForm, FormSpy, useFormEffects, LifeCycleTypes, createControllerBox, - useFormSpy, + useFormSpy } from '@formily/antd' import { setup } from '@formily/antd-components' setup() -const CustomSpy = createControllerBox('CustomSpy', (props) => { +const CustomSpy = createControllerBox('CustomSpy', props => { const { form } = useFormSpy({ selector: '*', reducer: v => v }) return
name: {form && form.getFieldValue('username')}
}) @@ -1106,7 +1155,6 @@ const App = () => { } ReactDOM.render(, document.getElementById('root')) - ``` #### useDeepFormItem @@ -1118,7 +1166,7 @@ ReactDOM.render(, document.getElementById('root')) ```tsx import { useDeepFormItem, FormItemDeepProvider } from '@formily/antd' import { Form } from '@alifd/antd' -const CustomComponent = (props) => { +const CustomComponent = props => { const { prefixCls, labelAlign, @@ -1126,22 +1174,25 @@ const CustomComponent = (props) => { wrapperCol: contextWrapperCol } = useDeepFormItem() - return - {props.children} - + return ( + + {props.children} + + ) } const App = () => { - return - - + return ( + + + + ) } - ``` #### useShallowFormItem @@ -1150,7 +1201,7 @@ const App = () => { **用法** -下列 `` 除了`label`以外,会继承其他所有顶部的 `FormItem` 属性。 +下列 `` 除了`label`以外,会继承其他所有顶部的 `FormItem` 属性。 ```tsx import { SchemaField, FormItemShallowProvider, useShallowFormItem } from '@formily/antd' @@ -1227,36 +1278,36 @@ setValidationLanguage('zh') #### setValidationLocale -设置校验规则命中时,message的定义, 搭配[setValidationLanguage](#setValidationLanguage) 使用 +设置校验规则命中时,message 的定义, 搭配[setValidationLanguage](#setValidationLanguage) 使用 **签名** ```typescript interface ILocaleMessages { - [key: string]: string | ILocaleMessages; + [key: string]: string | ILocaleMessages } interface ILocales { - [lang: string]: ILocaleMessages; + [lang: string]: ILocaleMessages } -const setValidationLocale: (locale: ILocales) => void; +const setValidationLocale: (locale: ILocales) => void ``` **用法** ```tsx -import { setValidationLanguage, setValidationLocale, } from '@formily/antd' +import { setValidationLanguage, setValidationLocale } from '@formily/antd' setValidationLanguage('zh') setValidationLocale({ zh: { - required: '这是修改默认的必填文案', - }, + required: '这是修改默认的必填文案' + } }) ``` #### registerValidationFormats -拓展校验正则format, 当不满足此规则时即报错。 +拓展校验正则 format, 当不满足此规则时即报错。 **签名** @@ -1304,8 +1355,8 @@ static (template: any) => void; import { setValidationLocale, registerValidationMTEngine } from '@formily/antd' setValidationLocale({ en: { - required: '这是定制必填文案 <% injectVar %>', - }, + required: '这是定制必填文案 <% injectVar %>' + } }) registerValidationMTEngine((message, context) => { @@ -1427,29 +1478,29 @@ ReactDOM.render(, document.getElementById('root')) #### connect -> 包装字段组件,让字段组件只需要支持value/defaultValue/onChange属性即可快速接入表单 +> 包装字段组件,让字段组件只需要支持 value/defaultValue/onChange 属性即可快速接入表单 ```typescript -type Connect = >(options?: IConnectOptions) => -(Target: T) => React.PureComponent +type Connect = >( + options?: IConnectOptions +) => (Target: T) => React.PureComponent ``` -* IConnectOptions - -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| valueName | value字段的名称 | string | `'value'` | -| eventName | 改变value的事件名 | string | `'onChange'` | -| defaultProps | 默认属性 | {} | {} | -| getValueFromEvent | 根据事件获取value | (event?: any, value?: any) => any | | -| getProps | 获取props的函数 | (componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => {} | void | | -| getComponent | 获取Component的函数 | (Target: any, componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => React.JSXElementConstructor | | +- IConnectOptions +| 参数 | 说明 | 类型 | 默认值 | +| :---------------- | :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------- | :----------- | +| valueName | value 字段的名称 | string | `'value'` | +| eventName | 改变 value 的事件名 | string | `'onChange'` | +| defaultProps | 默认属性 | {} | {} | +| getValueFromEvent | 根据事件获取 value | (event?: any, value?: any) => any | | +| getProps | 获取 props 的函数 | (componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => {} | void | | +| getComponent | 获取 Component 的函数 | (Target: any, componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => React.JSXElementConstructor | | **用法** ```typescript -import {registerFormField,connect} from '@formily/antd' +import { registerFormField, connect } from '@formily/antd' registerFormField( 'string', @@ -1485,7 +1536,6 @@ const Input = connect({ })(Input)) ``` - #### registerFormFields 全局批量注册拓展组件 @@ -1493,6 +1543,7 @@ const Input = connect({ ```typescript function registerFormFields(object: ISchemaFormRegistry['fields']) ``` + **用法** ```jsx @@ -1506,10 +1557,20 @@ import { } from '@formily/antd' // 或者 @formily/next const CustomComponent1 = props => { - return props.onChange(e.target.value)} /> + return ( + props.onChange(e.target.value)} + /> + ) } const CustomComponent2 = props => { - return props.onChange(e.target.value)} + /> + ) } registerFormFields({ @@ -1520,8 +1581,16 @@ registerFormFields({ const App = () => { return ( - - + + ) } @@ -1531,7 +1600,7 @@ ReactDOM.render(, document.getElementById('root')) #### registerFormComponent -全局扩展 `
` UI组件 +全局扩展 `` UI 组件 ```typescript function registerFormComponent( @@ -1544,7 +1613,11 @@ function registerFormComponent( ```tsx import React from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, SchemaMarkupField as Field, registerFormComponent } from '@formily/antd' +import { + SchemaForm, + SchemaMarkupField as Field, + registerFormComponent +} from '@formily/antd' import { Input } from '@formily/antd-components' registerFormComponent(props => { @@ -1567,9 +1640,7 @@ ReactDOM.render(, document.getElementById('root')) 全局扩展 `` UI 组件 ```typescript -function registerFormItemComponent( - component: React.JSXElementConstructor -) +function registerFormItemComponent(component: React.JSXElementConstructor) ``` **用法** @@ -1577,7 +1648,11 @@ function registerFormItemComponent( ```tsx import React from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, SchemaMarkupField as Field, registerFormItemComponent } from '@formily/antd' +import { + SchemaForm, + SchemaMarkupField as Field, + registerFormItemComponent +} from '@formily/antd' import { Input } from '@formily/antd-components' registerFormItemComponent(props => { @@ -1595,7 +1670,6 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - #### registerFormField ```typescript @@ -1609,8 +1683,12 @@ type registerFormField( **用法** ```tsx - -import SchemaForm, { SchemaMarkupField as Field, registerFormField, connect, createFormActions } from '@formily/antd' +import SchemaForm, { + SchemaMarkupField as Field, + registerFormField, + connect, + createFormActions +} from '@formily/antd' registerFormField( 'custom-string', @@ -1620,7 +1698,7 @@ const actions = createFormActions() const App = () => { return ( - + ) @@ -1643,23 +1721,28 @@ function createControllerBox( **用法** ```jsx - -import SchemaForm, { SchemaMarkupField as Field, createControllerBox, createFormActions } from '@formily/antd' +import SchemaForm, { + SchemaMarkupField as Field, + createControllerBox, + createFormActions +} from '@formily/antd' import { Input } from '@formily/antd-components' -const FormLayout = createControllerBox('controller-form-layout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+const FormLayout = createControllerBox('controller-form-layout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) const App = () => { return ( - + - + ) } @@ -1681,25 +1764,32 @@ function createVirtualBox( **用法** ```jsx - -import SchemaForm, { SchemaMarkupField as Field, createVirtualBox, createFormActions } from '@formily/antd' +import SchemaForm, { + SchemaMarkupField as Field, + createVirtualBox, + createFormActions +} from '@formily/antd' import { Input } from '@formily/antd-components' -const FormLayout = createVirtualBox('form-layout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+const FormLayout = createVirtualBox('form-layout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) const App = () => { return ( - - + + - + ) } @@ -1721,20 +1811,25 @@ function registerVirtualBox( **用法** ```jsx - -import SchemaForm, { SchemaMarkupField as Field, registerVirtualBox, createFormActions } from '@formily/antd' +import SchemaForm, { + SchemaMarkupField as Field, + registerVirtualBox, + createFormActions +} from '@formily/antd' import { Input } from '@formily/antd-components' -registerVirtualBox('form-layout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+registerVirtualBox('form-layout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) const App = () => { return ( - + { }} > - + ) } @@ -1773,14 +1868,18 @@ function getRegistry () => ISchemaFormRegistry **用法** ```tsx +import SchemaForm, { + SchemaMarkupField as Field, + getRegistry +} from '@formily/antd' -import SchemaForm, { SchemaMarkupField as Field, getRegistry } from '@formily/antd' - -registerVirtualBox('CustomLayout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+registerVirtualBox('CustomLayout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) getRegistry() @@ -1791,20 +1890,24 @@ getRegistry() 清理预先注册的所有组件。 ```typescript -function cleanRegistry () +function cleanRegistry() ``` **用法** ```tsx +import SchemaForm, { + SchemaMarkupField as Field, + cleanRegistry +} from '@formily/antd' -import SchemaForm, { SchemaMarkupField as Field, cleanRegistry } from '@formily/antd' - -registerVirtualBox('CustomLayout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+registerVirtualBox('CustomLayout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) cleanRegistry() @@ -1879,7 +1982,6 @@ interface ISchema { } ``` - #### IFormActions ```typescript @@ -1925,7 +2027,7 @@ interface IFormActions { //重置范围,用于批量或者精确控制要重置的字段 selector?: FormPathPattern //是否清空默认值 - clearInitialValue?:boolean + clearInitialValue?: boolean }): Promise /* @@ -2055,7 +2157,7 @@ interface IFormAsyncActions { //重置范围,用于批量或者精确控制要重置的字段 selector?: FormPathPattern //是否清空默认值 - clearInitialValue?:boolean + clearInitialValue?: boolean }): Promise /* * 获取状态变化情况,主要用于在表单生命周期钩子内判断当前生命周期中有哪些状态发生了变化, @@ -2126,7 +2228,6 @@ interface IFormAsyncActions { } ``` - #### ButtonProps ```typescript @@ -2208,7 +2309,6 @@ interface ISchemaFieldAdaptorProps } ``` - #### IFieldState ```typescript @@ -2275,7 +2375,6 @@ interface IFieldState { } ``` - #### ISchemaFieldComponentProps ```typescript @@ -2350,7 +2449,6 @@ interface ISchemaFormRegistry { } ``` - #### InternalFormats ```typescript @@ -2447,23 +2545,25 @@ interface IPreviewTextProps { innerAfter?: React.ReactNode addonAfter?: React.ReactNode } - ``` #### IMutators ```typescript interface IMutators { - change: (value: V)=> void,//改变当前字段值 - dispatch: (name: string, payload : any) => void,//触发effect事件 - errors: (errors: string | Array, ...formatValues: Array) => void,//设置当前字段的错误消息 - push(value: V),//对当前字段的值做push操作 - pop(),//对当前字段的值做pop操作 - insert(index: number,value: V),//对当前字段的值做insert操作 - remove(name : string),//对当前字段的值做remove操作 - unshift(value : V),//对当前字段值做unshift操作 - shift(),//对当前字段值做shift操作 - move(fromIndex: number, toIndex: number)//对当前字段值做move操作 + change: (value: V) => void //改变当前字段值 + dispatch: (name: string, payload: any) => void //触发effect事件 + errors: ( + errors: string | Array, + ...formatValues: Array + ) => void //设置当前字段的错误消息 + push(value: V) //对当前字段的值做push操作 + pop() //对当前字段的值做pop操作 + insert(index: number, value: V) //对当前字段的值做insert操作 + remove(name: string) //对当前字段的值做remove操作 + unshift(value: V) //对当前字段值做unshift操作 + shift() //对当前字段值做shift操作 + move(fromIndex: number, toIndex: number) //对当前字段值做move操作 } ``` @@ -2471,26 +2571,32 @@ interface IMutators { ```typescript interface IFieldProps { - name : string //字段数据路径 - path : Array //字段数组数据路径 - value : V //字段值 - errors : Array //字段错误消息集合 - editable : boolean | ((name:string) => boolean) //字段是否可编辑 - locale : Locale //国际化文案对象 - loading : boolean //是否处于加载态 - schemaPath : Array //schema path,考虑到有些schema其实是不占数据路径的,所以这个路径是真实路径 - getSchema : (path: string) => ISchema //根据路径获取schema - renderField : (childKey: string, reactKey: string | number) => JSX.Element | string | null //根据childKey渲染当前字段的子字段 - renderComponent : React.FunctionComponent | undefined>,//渲染当前字段的组件,对于x-render来说,可以借助它快速实现渲染包装功能 - getOrderProperties : () => Array<{schema: ISchema, key: number, path: string, name: string }>,//根据properties里字段的x-index值求出排序后的properties - mutators : Mutators,//数据操作对象 - schema : ISchema + name: string //字段数据路径 + path: Array //字段数组数据路径 + value: V //字段值 + errors: Array //字段错误消息集合 + editable: boolean | ((name: string) => boolean) //字段是否可编辑 + locale: Locale //国际化文案对象 + loading: boolean //是否处于加载态 + schemaPath: Array //schema path,考虑到有些schema其实是不占数据路径的,所以这个路径是真实路径 + getSchema: (path: string) => ISchema //根据路径获取schema + renderField: ( + childKey: string, + reactKey: string | number + ) => JSX.Element | string | null //根据childKey渲染当前字段的子字段 + renderComponent: React.FunctionComponent | undefined> //渲染当前字段的组件,对于x-render来说,可以借助它快速实现渲染包装功能 + getOrderProperties: () => Array<{ + schema: ISchema + key: number + path: string + name: string + }> //根据properties里字段的x-index值求出排序后的properties + mutators: Mutators //数据操作对象 + schema: ISchema } - ``` ```typescript - interface IConnectOptions { //控制表单组件 valueName?: string @@ -2499,20 +2605,25 @@ interface IConnectOptions { //默认props defaultProps?: Partial //取值函数,有些场景我们的事件函数取值并不是事件回调的第一个参数,需要做进一步的定制 - getValueFromEvent?: (props: IFieldProps['x-props'], event: Event, ...args: any[]) => any + getValueFromEvent?: ( + props: IFieldProps['x-props'], + event: Event, + ...args: any[] + ) => any //字段组件props transformer - getProps?: (connectProps: IConnectProps, fieldProps: IFieldProps) => IConnectProps + getProps?: ( + connectProps: IConnectProps, + fieldProps: IFieldProps + ) => IConnectProps //字段组件component transformer - getComponent?: ( - target: T, + getComponent?: ( + target: T, connectProps: IConnectProps, fieldProps: IFieldProps ) => T } - ``` - ### IForm ```typescript @@ -2586,42 +2697,49 @@ interface IFormActions { setFieldInitialValue(path?: FormPathPattern, value?: any): void getFieldInitialValue(path?: FormPathPattern): any } - ``` #### IFormValidateResult ```typescript interface IFormValidateResult { - errors: Array<{ - path: string; - messages: string[]; - }>; - warnings: Array<{ - path: string; - messages: string[]; - }>; + errors: Array<{ + path: string + messages: string[] + }> + warnings: Array<{ + path: string + messages: string[] + }> } ``` #### IFormProps ```typescript -interface IFormProps { - value?: Value; - defaultValue?: DefaultValue; - initialValues?: DefaultValue; - actions?: FormActions; - effects?: IFormEffect; - form?: IForm; - onChange?: (values: Value) => void; - onSubmit?: (values: Value) => void | Promise; - onReset?: () => void; - onValidateFailed?: (valideted: IFormValidateResult) => void; - children?: React.ReactElement | React.ReactElement[] | ((form: IForm) => React.ReactElement); - useDirty?: boolean; - editable?: boolean | ((name: string) => boolean); - validateFirst?: boolean; +interface IFormProps< + Value = {}, + DefaultValue = {}, + FormEffectPayload = any, + FormActions = any +> { + value?: Value + defaultValue?: DefaultValue + initialValues?: DefaultValue + actions?: FormActions + effects?: IFormEffect + form?: IForm + onChange?: (values: Value) => void + onSubmit?: (values: Value) => void | Promise + onReset?: () => void + onValidateFailed?: (valideted: IFormValidateResult) => void + children?: + | React.ReactElement + | React.ReactElement[] + | ((form: IForm) => React.ReactElement) + useDirty?: boolean + editable?: boolean | ((name: string) => boolean) + validateFirst?: boolean } ``` @@ -2678,7 +2796,6 @@ interface MergedFieldComponentProps extends IFieldState { reactKey?: string | number ) => React.ReactElement } - ``` #### Pagination @@ -2722,4 +2839,4 @@ type IQueryResponse = { pageSize: number current: number } -``` \ No newline at end of file +``` diff --git a/packages/core/README.md b/packages/core/README.md index 91d2a42fcdf..61d9e009526 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -436,7 +436,7 @@ enum LifeCycleTypes { // Form pre-initialization trigger ON_FORM_SUBMIT_VALIDATE_START = 'onFormSubmitValidateStart', // Triggered when the form submission ends due to validate successs - ON_FORM_SUBMIT_VALIDATE_SUCCESS= 'onFormSubmitValidateSuccess', + ON_FORM_SUBMIT_VALIDATE_SUCCESS = 'onFormSubmitValidateSuccess', // Triggered when the form submission ends due to validate failed ON_FORM_SUBMIT_VALIDATE_FAILED = 'onFormSubmitValidateFailed', @@ -487,7 +487,7 @@ enum LifeCycleTypes { // Form pre-initialization trigger ON_FIELD_MOUNT = 'onFieldMount', // Trigger when the field is unloaded - ON_FIELD_UNMOUNT = 'onFieldUnmount', + ON_FIELD_UNMOUNT = 'onFieldUnmount' } ``` @@ -773,7 +773,7 @@ interface ValidateDescription { // Customize with regularity pattern?: RegExp | string // Maximum length rule - max?: number; + max?: number // Maximum numerical rule maximum?: number // Exclusive maximum numerical rule diff --git a/packages/core/README.zh-cn.md b/packages/core/README.zh-cn.md index 6f696b2d7c4..086ea64d778 100644 --- a/packages/core/README.zh-cn.md +++ b/packages/core/README.zh-cn.md @@ -48,7 +48,6 @@ npm install --save @formily/core ### 背景 - 中后台领域,核心就是两种场景,**一个是数据录入,一个是数据查询+数据展现**,不管 是数据录入还是数据查询,都是借助表单来实现的,从实现复杂度来看,两者复杂度相差不 多,因为数据呈现层面难免会有极度复杂的呈现形式(比如 Tree Table 等等),但是,数据 @@ -62,7 +61,6 @@ npm install --save @formily/core ### 核心亮点 - - 时间旅行,借助首创 Observable Graph,可以记录任意时刻的全量状态,也可以将状态 回滚至任意时刻,这样的能力在,重事务型应用与本地调试上可以发挥出最大价值 - 高效更新,精确渲染,无需整树渲染 @@ -84,7 +82,6 @@ npm install --save @formily/core ### 术语解释 - **FormPath/FormPathPattern** 是一个抽象数据路径形式,FormPath 是路径类 ,FormPathPattern 是可以被 FormPath 解析的路径形式,在这里主要使用了 [cool-path](https://github.com/janrywang/cool-path) 路径解析匹配,求值取值能力 @@ -113,7 +110,6 @@ Graph 中作为一个独立节点而存在,但是这个节点类型就是一 - d 字段的 name 属性是 a.d,path 属性是 a.d - e 字段的 name 属性是 a.d.e,path 属性是 a.d.e - 这一来解释之后,我们就大概明白了,只要在某个节点路径中,存在 VirtualField,那么 它的数据路径就会略过 VirtualField,但是,对于 VirtualField 自身这个节点,它的 name 属性,是包含它自身的节点标识的,这就是为什么 b 字段的 name 属性是 a.b 的原 @@ -143,7 +139,7 @@ const form = createForm({ initialValues: {}, onChange: values => { console.log(values) - }, + } }) const aa = form.registerField({ @@ -174,7 +170,7 @@ registerValidationFormats(formats:{ import { createForm, registerValidationFormats } from '@formily/core' registerValidationFormats({ - number: /^[+-]?\d+(\.\d+)?$/, + number: /^[+-]?\d+(\.\d+)?$/ }) const form = createForm({ @@ -182,7 +178,7 @@ const form = createForm({ initialValues: {}, onChange: values => { console.log(values) - }, + } }) const aa = form.registerField({ @@ -232,7 +228,7 @@ import { createForm, registerValidationRules } from '@formily/core' registerValidationRules({ custom: value => { return value === '123' ? 'This field can not be 123' : '' - }, + } }) const form = createForm({ @@ -240,16 +236,16 @@ const form = createForm({ initialValues: {}, onChange: values => { console.log(values) - }, + } }) const aa = form.registerField({ path: 'aa', rules: [ { - custom: true, - }, - ], + custom: true + } + ] }) aa.setState(state => { @@ -433,11 +429,11 @@ enum LifeCycleTypes { ON_FORM_MOUNT = 'onFormMount', //表单挂载时触发 ON_FORM_UNMOUNT = 'onFormUnmount', //表单卸载时触发 ON_FORM_SUBMIT = 'onFormSubmit', //表单提交时触发 - ON_FORM_RESET = 'onFormReset', //表单重置时触发 + ON_FORM_RESET = 'onFormReset', //表单重置时触发 ON_FORM_SUBMIT_START = 'onFormSubmitStart', //表单提交开始时触发 ON_FORM_SUBMIT_END = 'onFormSubmitEnd', //表单提交结束时触发 ON_FORM_SUBMIT_VALIDATE_START = 'onFormSubmitValidateStart', // 表单提交触发的校验 - ON_FORM_SUBMIT_VALIDATE_SUCCESS= 'onFormSubmitValidateSuccess', // 表单提交时因为校验成功而触发 + ON_FORM_SUBMIT_VALIDATE_SUCCESS = 'onFormSubmitValidateSuccess', // 表单提交时因为校验成功而触发 ON_FORM_SUBMIT_VALIDATE_FAILED = 'onFormSubmitValidateFailed', // 表单提交时因为校验失败而触发 ON_FORM_ON_SUBMIT_SUCCESS = 'onFormOnSubmitSuccess', // 表单自定义onSubmit成功 ON_FORM_ON_SUBMIT_FAILED = 'onFormOnSubmitFailed', // 表单自定义onSubmit失败 diff --git a/packages/meet-components/README.md b/packages/meet-components/README.md index d0e974659f1..3769327b840 100644 --- a/packages/meet-components/README.md +++ b/packages/meet-components/README.md @@ -5,5 +5,3 @@ ```bash npm install --save @formily/meet-components ``` - - diff --git a/packages/meet-components/README.zh-cn.md b/packages/meet-components/README.zh-cn.md index 7746434466d..2d1b22cbe8b 100644 --- a/packages/meet-components/README.zh-cn.md +++ b/packages/meet-components/README.zh-cn.md @@ -11,62 +11,57 @@ npm install --save @formily/meet-components 通过 `setup` 方法,可以快速置入内置的表单组件,免去维护全局`components`的工作。 ```tsx -import { SchemaForm, SchemaMarkupField as Field, FormButtonGroup, Submit } from '@formily/meet' +import { + SchemaForm, + SchemaMarkupField as Field, + FormButtonGroup, + Submit +} from '@formily/meet' import { setup } from '@formily/meet-components' setup() export default () => { return ( - + ) } - ``` ### 内置组件类型 通过 `setup`后,内置的表单字段有以下类型 -| type类型 | 对应组件 | 描述 | -|:--------------|:----------------------------------|:----------------------| -| string | [Input](#Input) | 输入框组件 | -| string(有enum属性时) | [Select](#Select) | 选择框组件 | -| password | [Password](#Password) | 密码输入框 | -| checkbox | [CheckboxGroup](#Checkbox) | Checkbox | -| radio | [RadioGroup](#Radio) | Radio | -| boolean | [Switch](#Swicth) | 开关组件 | -| date | [DatePicker](#DatePicker) | 日期选择器 | -| time | [TimePicker](#TimePicker) | 时间选择器 | -| daterange | [DatePicker.RangePicker](#RangePicker) | 范围日期选择器 | - +| type 类型 | 对应组件 | 描述 | +| :--------------------- | :------------------------------------- | :------------- | +| string | [Input](#Input) | 输入框组件 | +| string(有 enum 属性时) | [Select](#Select) | 选择框组件 | +| password | [Password](#Password) | 密码输入框 | +| checkbox | [CheckboxGroup](#Checkbox) | Checkbox | +| radio | [RadioGroup](#Radio) | Radio | +| boolean | [Switch](#Swicth) | 开关组件 | +| date | [DatePicker](#DatePicker) | 日期选择器 | +| time | [TimePicker](#TimePicker) | 时间选择器 | +| daterange | [DatePicker.RangePicker](#RangePicker) | 范围日期选择器 | #### Input -* JSON Schema 方式 +- JSON Schema 方式 ```jsx -import { createElement, useState } from 'rax'; -import { useLocale } from '@rax-ui/locale'; -import { ConfigProvider } from '@alifd/meet'; -import { - SchemaForm, -} from '@formily/meet'; +import { createElement, useState } from 'rax' +import { useLocale } from '@rax-ui/locale' +import { ConfigProvider } from '@alifd/meet' +import { SchemaForm } from '@formily/meet' -import { - setup, -} from '@formily/meet-components'; +import { setup } from '@formily/meet-components' const App = () => { return ( { 'x-component': 'Input', 'x-component-props': { placeholder: 'input' - }, - }, + } + } } }} - > - + >
) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Input } from '@formily/meet-components' @@ -103,7 +97,7 @@ const App = () => { return ( { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - #### Select -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - - -import { createElement, useState } from 'rax'; -import View from 'rax-view'; -import { useLocale } from '@rax-ui/locale'; -import { ConfigProvider } from '@alifd/meet'; -import { - SchemaForm, -} from '@formily/meet'; +import { createElement, useState } from 'rax' +import View from 'rax-view' +import { useLocale } from '@rax-ui/locale' +import { ConfigProvider } from '@alifd/meet' +import { SchemaForm } from '@formily/meet' import { Select } from '@formily/meet-components' -import { - setup, -} from '@formily/meet-components'; - +import { setup } from '@formily/meet-components' const App = () => { return ( { 'x-component': 'Select', 'x-component-props': { placeholder: 'select' - }, + } }, objSelect: { title: 'Object Select', @@ -172,27 +158,25 @@ const App = () => { ], 'x-component-props': { placeholder: 'select' - }, - }, + } + } } }} - > - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Select } from '@formily/meet-components' @@ -200,7 +184,7 @@ const App = () => { return ( { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - #### TextArea -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { Input } from '@formily/meet-components' - const App = () => { return ( { 'x-component': 'TextArea', 'x-component-props': { placeholder: 'textarea' - }, - }, + } + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Input } from '@formily/meet-components' - const App = () => { return ( - + { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - #### Password -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { Password } from '@formily/meet-components' - const App = () => { return ( { 'x-component': 'Password', 'x-component-props': { placeholder: 'Password' - }, - }, + } + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Password } from '@formily/meet-components' - const App = () => { return ( - + { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - #### NumberPicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { NumberPicker } from '@formily/meet-components' - const App = () => { return ( { properties: { textarea: { title: 'NumberPicker', - 'x-component': 'NumberPicker', - }, + 'x-component': 'NumberPicker' + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { NumberPicker } from '@formily/meet-components' - const App = () => { return ( - + { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - #### Switch -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { Switch } from '@formily/meet-components' - const App = () => { return ( { properties: { textarea: { title: 'Switch', - 'x-component': 'Switch', - }, + 'x-component': 'Switch' + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Switch } from '@formily/meet-components' - const App = () => { return ( - - + + ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - #### DatePicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { DatePicker } from '@formily/meet-components' - const App = () => { return ( { 'x-component': 'DatePicker', 'x-component-props': { format: 'YYYY-MM-DD HH:mm:ss' - }, - }, + } + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { DatePicker } from '@formily/meet-components' - const App = () => { return ( - + { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - #### RangePicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { DatePicker } from '@formily/meet-components' - const App = () => { return ( { properties: { '[start,end]': { title: 'RangePicker', - 'x-component': 'RangePicker', - }, + 'x-component': 'RangePicker' + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { DatePicker } from '@formily/meet-components' - const App = () => { return ( - - + + ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - - - #### MonthPicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { DatePicker } from '@formily/meet-components' - const App = () => { return ( { properties: { textarea: { title: 'MonthPicker', - 'x-component': 'MonthPicker', - }, + 'x-component': 'MonthPicker' + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { DatePicker } from '@formily/meet-components' - const App = () => { return ( - - + + ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - #### TimePicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { TimePicker } from '@formily/meet-components' - const App = () => { return ( { 'x-component': 'TimePicker', 'x-component-props': { format: 'YYYY-MM-DD HH:mm:ss' - }, - }, + } + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { TimePicker } from '@formily/meet-components' - const App = () => { return ( - + { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - #### Range -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { Range } from '@formily/meet-components' - const App = () => { return ( { max: 1024, marks: [0, 1024] } - }, + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Range } from '@formily/meet-components' - const App = () => { return ( - + { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - #### Upload -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { Upload } from '@formily/meet-components' - const App = () => { return ( { 'x-component-props': { listType: 'text' } - }, + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Upload } from '@formily/meet-components' - const App = () => { return ( - + { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` #### Checkbox -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { Checkbox } from '@formily/meet-components' - const App = () => { return ( { { label: 'Three', value: '3' }, { label: 'Four', value: '4' } ] - }, + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Checkbox } from '@formily/meet-components' - const App = () => { return ( { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - #### Radio -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { Radio } from '@formily/meet-components' - const App = () => { return ( { { label: 'Three', value: '3' }, { label: 'Four', value: '4' } ] - }, + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Radio } from '@formily/meet-components' - const App = () => { return ( { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - #### Rating -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { Rating } from '@formily/meet-components' - const App = () => { return ( { 'x-component-props': { allowHalf: true } - }, + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Rating } from '@formily/meet-components' - const App = () => { return ( { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - #### Transfer -* JSON Schema 方式 +- JSON Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/meet' +import { createElement, useState } from 'rax' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/meet' import { Transfer } from '@formily/meet-components' - const App = () => { return ( { 'x-component-props': { showSearch: true } - }, + } } }} - > - - + > ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx - -import { createElement, useState } from 'rax'; +import { createElement, useState } from 'rax' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/meet' import { Transfer } from '@formily/meet-components' - const App = () => { return ( { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` diff --git a/packages/meet/README.md b/packages/meet/README.md index 5ec7b32d363..fe5d78ae61a 100644 --- a/packages/meet/README.md +++ b/packages/meet/README.md @@ -5,5 +5,3 @@ ```bash npm install --save @formily/meet ``` - - diff --git a/packages/meet/README.zh-cn.md b/packages/meet/README.zh-cn.md index bdf8498226e..4d55f7d4e6a 100644 --- a/packages/meet/README.zh-cn.md +++ b/packages/meet/README.zh-cn.md @@ -12,292 +12,287 @@ npm install --save @formily/meet #### `` -基于@formily/react 的核心组件SchemaForm进一步扩展出来的SchemaForm组件,推荐生产环境下使用 - -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| schema |通过schema渲染表单 | [ISchema](#ISchema) | | -| fields |传入自定义表单组件 | { [key: string]: [ISchemaFieldComponent](#ISchemaFieldComponent) } | | -| virtualFields |传入自定义虚拟组件 | { [key: string]: [ISchemaVirtualFieldComponent](#ISchemaVirtualFieldComponent) } | | -| formComponent |全局注册Form渲染组件 | string `or` React.ReactElement | | -| formItemComponent |全局注册FormItem渲染组件 | React.ReactElement | | -| labelCol |label布局控制 | number `or` { span: number; offset?: number } | | -| wrapperCol |FormItem布局控制 | number `or` { span: number; offset?: number } | | -| previewPlaceholder |自定义预览placeholder | string `or` ((props: [IPreviewTextProps](#IPreviewTextProps)) => string) | | -| prefix |样式前缀 | string | | -| inline |是否为内联表单 | boolean | | -| size |单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。 | 'large' `or` 'medium' `or` 'small' | | -| labelAlign |标签的位置 | 'top' `or` 'left' `or` 'inset' | | -| labelTextAlign |标签的左右对齐方式 | 'left' `or` 'right' | | -| labelCol |控制所有 Item 的 labelCol | `{}` | | -| wrapperCol |控制所有 Item 的 wrapperCol | `{}` | | -| className |扩展class | string | | -| style |自定义内联样式 | React.CSSProperties | | -| component |设置标签类型 | string `or` (() => void) | | -| value |全局value | {} | | -| defaultValue |全局defaultValue | {} | | -| initialValues |全局initialValues | {} | | -| actions |FormActions实例 | [FormActions](#FormActions) | | -| effects |IFormEffect实例 | IFormEffect | | -| form |表单实例 | [IForm](#IForm) | | -| onChange |表单变化回调 | (values: {}) => void | | -| onSubmit |form内有 `htmlType="submit"` 或 actions.submit时 触发 | (values: {}) => void `or` Promise<{}> | | -| onReset |form内有 或 actions.reset时 触发 | () => void | | -| onValidateFailed |校验失败时触发 | (valideted: [IFormValidateResult](#IFormValidateResult)) => void | | -| children |全局value | React.ReactElement `or` ((form: [IForm](#IForm)) => React.ReactElement) | | -| useDirty |是否使用脏检查,默认会走immer精确更新 | boolean | | -| editable |是否可编辑 | boolean `or` ((name: string) => boolean) | | -| validateFirst |是否走悲观校验,遇到第一个校验失败就停止后续校验 | boolean | | - +基于@formily/react 的核心组件 SchemaForm 进一步扩展出来的 SchemaForm 组件,推荐生产环境下使用 + +| 参数 | 说明 | 类型 | 默认值 | +| :----------------- | :------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------- | :----- | +| schema | 通过 schema 渲染表单 | [ISchema](#ISchema) | | +| fields | 传入自定义表单组件 | { [key: string]: [ISchemaFieldComponent](#ISchemaFieldComponent) } | | +| virtualFields | 传入自定义虚拟组件 | { [key: string]: [ISchemaVirtualFieldComponent](#ISchemaVirtualFieldComponent) } | | +| formComponent | 全局注册 Form 渲染组件 | string `or` React.ReactElement | | +| formItemComponent | 全局注册 FormItem 渲染组件 | React.ReactElement | | +| labelCol | label 布局控制 | number `or` { span: number; offset?: number } | | +| wrapperCol | FormItem 布局控制 | number `or` { span: number; offset?: number } | | +| previewPlaceholder | 自定义预览 placeholder | string `or` ((props: [IPreviewTextProps](#IPreviewTextProps)) => string) | | +| prefix | 样式前缀 | string | | +| inline | 是否为内联表单 | boolean | | +| size | 单个 Item 的 size 自定义,优先级高于 Form 的 size, 并且当组件与 Item 一起使用时,组件自身设置 size 属性无效。 | 'large' `or` 'medium' `or` 'small' | | +| labelAlign | 标签的位置 | 'top' `or` 'left' `or` 'inset' | | +| labelTextAlign | 标签的左右对齐方式 | 'left' `or` 'right' | | +| labelCol | 控制所有 Item 的 labelCol | `{}` | | +| wrapperCol | 控制所有 Item 的 wrapperCol | `{}` | | +| className | 扩展 class | string | | +| style | 自定义内联样式 | React.CSSProperties | | +| component | 设置标签类型 | string `or` (() => void) | | +| value | 全局 value | {} | | +| defaultValue | 全局 defaultValue | {} | | +| initialValues | 全局 initialValues | {} | | +| actions | FormActions 实例 | [FormActions](#FormActions) | | +| effects | IFormEffect 实例 | IFormEffect | | +| form | 表单实例 | [IForm](#IForm) | | +| onChange | 表单变化回调 | (values: {}) => void | | +| onSubmit | form 内有 `htmlType="submit"` 或 actions.submit 时 触发 | (values: {}) => void `or` Promise<{}> | | +| onReset | form 内有 或 actions.reset 时 触发 | () => void | | +| onValidateFailed | 校验失败时触发 | (valideted: [IFormValidateResult](#IFormValidateResult)) => void | | +| children | 全局 value | React.ReactElement `or` ((form: [IForm](#IForm)) => React.ReactElement) | | +| useDirty | 是否使用脏检查,默认会走 immer 精确更新 | boolean | | +| editable | 是否可编辑 | boolean `or` ((name: string) => boolean) | | +| validateFirst | 是否走悲观校验,遇到第一个校验失败就停止后续校验 | boolean | | #### `` > @formily/meet 的核心组件,用于描述表单字段 -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| name |字段名 | string | | -| title |字段label | React.ReactNode | | -| description |字段描述信息 | React.ReactNode | | -| readOnly | 只读 | boolean | | -| writeOnly | 只写 | boolean | | -| type | 字段类型 | 'string' `or` 'object' `or` 'array' `or` 'number' `or` string | | -| enum | 相当于字段dataSource | `Array` | | -| required | 是否必填,为true会同时设置校验规则 | string[] `or` boolean | | -| format | 正则规则类型,详细类型可以往后看 | string | | -| properties | 对象属性 | { [key: string]: [ISchema](#ISchema) } | | -| items | 数组描述 | [ISchema](#ISchema) `or` [ISchema](#ISchema)[] | | -| patternProperties | 动态匹配对象的某个属性的 Schema | { [key: string]: [ISchema](#ISchema) } | | -| additionalProperties | 匹配对象额外属性的 Schema | [ISchema](#ISchema) | | -| editable | 字段是否可编辑 | boolean | | -| visible | 字段是否显示(伴随value的显示和隐藏) | boolean | | -| display | 字段是否显示(纯视觉,不影响value) | boolean | | -| x-component | 用于渲染的组件 | string | | -| x-component-props | 组件的属性 | { [name: string]: any } | | -| x-rules | 校验规则 | [ValidatePatternRules](#ValidatePatternRules) | | -| x-props | 字段扩展属性 | { [name: string]: any } | | -| x-index | 字段顺序 | number | | -| default | 字段默认值 | any | | -| const | 校验字段值是否与 const 的值相等 | any | | -| multipleOf | 校验字段值是否可被 multipleOf 的值整除 | number | | -| maximum | 最大值 | number | | -| exclusiveMaximum | 校验最大值(大于等于) | number | | -| minimum | 最小值 | number | | -| exclusiveMinimum | 最小值(小于等于) | number | | -| maxLength | 最大长度 | number | | -| minLength | 最小长度 | number | | -| pattern | 正则校验规则 | string `or` RegExp | | -| maxItems | 最大项数 | number | | -| minItems | 最小项数 | number | | +| 参数 | 说明 | 类型 | 默认值 | +| :------------------- | :-------------------------------------- | :---------------------------------------------------------------- | :----- | +| name | 字段名 | string | | +| title | 字段 label | React.ReactNode | | +| description | 字段描述信息 | React.ReactNode | | +| readOnly | 只读 | boolean | | +| writeOnly | 只写 | boolean | | +| type | 字段类型 | 'string' `or` 'object' `or` 'array' `or` 'number' `or` string | | +| enum | 相当于字段 dataSource | `Array` | | +| required | 是否必填,为 true 会同时设置校验规则 | string[] `or` boolean | | +| format | 正则规则类型,详细类型可以往后看 | string | | +| properties | 对象属性 | { [key: string]: [ISchema](#ISchema) } | | +| items | 数组描述 | [ISchema](#ISchema) `or` [ISchema](#ISchema)[] | | +| patternProperties | 动态匹配对象的某个属性的 Schema | { [key: string]: [ISchema](#ISchema) } | | +| additionalProperties | 匹配对象额外属性的 Schema | [ISchema](#ISchema) | | +| editable | 字段是否可编辑 | boolean | | +| visible | 字段是否显示(伴随 value 的显示和隐藏) | boolean | | +| display | 字段是否显示(纯视觉,不影响 value) | boolean | | +| x-component | 用于渲染的组件 | string | | +| x-component-props | 组件的属性 | { [name: string]: any } | | +| x-rules | 校验规则 | [ValidatePatternRules](#ValidatePatternRules) | | +| x-props | 字段扩展属性 | { [name: string]: any } | | +| x-index | 字段顺序 | number | | +| default | 字段默认值 | any | | +| const | 校验字段值是否与 const 的值相等 | any | | +| multipleOf | 校验字段值是否可被 multipleOf 的值整除 | number | | +| maximum | 最大值 | number | | +| exclusiveMaximum | 校验最大值(大于等于) | number | | +| minimum | 最小值 | number | | +| exclusiveMinimum | 最小值(小于等于) | number | | +| maxLength | 最大长度 | number | | +| minLength | 最小长度 | number | | +| pattern | 正则校验规则 | string `or` RegExp | | +| maxItems | 最大项数 | number | | +| minItems | 最小项数 | number | | #### `` > Submit 组件 Props -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| onSubmit |触发提交的回调函数 | [ISchemaFormProps.onSubmit](#ISchemaFormProps) | | -| showLoading |是否展示loading | boolean | | -| type |按钮的类型 | 'primary' `or` 'secondary' `or` 'normal' | | -| size |按钮的尺寸 | 'small' `or` 'medium' `or` 'large' | | -| iconSize |按钮中 Icon 的尺寸,用于替代 Icon 的默认大小 | 'xxs' `or` 'xs' `or` 'small' `or` 'medium' `or` 'large' `or` 'xl' `or` 'xxl' `or` 'xxxl' | | -| htmlType |当 component = 'button' 时,设置 button 标签的 type 值 | 'submit' `or` 'reset' `or` 'button' | | -| component |设置标签类型 | 'button' `or` 'a' | | -| loading |设置按钮的载入状态 | boolean | | -| ghost |是否为幽灵按钮 | true `or` false `or` 'light' `or` 'dark' | | -| text |是否为文本按钮 | boolean | | -| warning |是否为警告按钮 | boolean | | -| disabled |是否禁用 | boolean | | -| onClick |点击按钮的回调 | (e: {}) => void | | -| href |在Button组件使用component属性值为a时有效,代表链接页面的URL | string | | -| target |在Button组件使用component属性值为a时有效,代表何处打开链接文档 | string | | - +| 参数 | 说明 | 类型 | 默认值 | +| :---------- | :------------------------------------------------------------------- | :--------------------------------------------------------------------------------------- | :----- | +| onSubmit | 触发提交的回调函数 | [ISchemaFormProps.onSubmit](#ISchemaFormProps) | | +| showLoading | 是否展示 loading | boolean | | +| type | 按钮的类型 | 'primary' `or` 'secondary' `or` 'normal' | | +| size | 按钮的尺寸 | 'small' `or` 'medium' `or` 'large' | | +| iconSize | 按钮中 Icon 的尺寸,用于替代 Icon 的默认大小 | 'xxs' `or` 'xs' `or` 'small' `or` 'medium' `or` 'large' `or` 'xl' `or` 'xxl' `or` 'xxxl' | | +| htmlType | 当 component = 'button' 时,设置 button 标签的 type 值 | 'submit' `or` 'reset' `or` 'button' | | +| component | 设置标签类型 | 'button' `or` 'a' | | +| loading | 设置按钮的载入状态 | boolean | | +| ghost | 是否为幽灵按钮 | true `or` false `or` 'light' `or` 'dark' | | +| text | 是否为文本按钮 | boolean | | +| warning | 是否为警告按钮 | boolean | | +| disabled | 是否禁用 | boolean | | +| onClick | 点击按钮的回调 | (e: {}) => void | | +| href | 在 Button 组件使用 component 属性值为 a 时有效,代表链接页面的 URL | string | | +| target | 在 Button 组件使用 component 属性值为 a 时有效,代表何处打开链接文档 | string | | #### `` > Reset 组件 Props -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| forceClear |是否清空 | boolean | | -| validate |是否触发校验 | boolean | | -| type |按钮的类型 | 'primary' `or` 'secondary' `or` 'normal' | | -| size |按钮的尺寸 | 'small' `or` 'medium' `or` 'large' | | -| iconSize |按钮中 Icon 的尺寸,用于替代 Icon 的默认大小 | 'xxs' `or` 'xs' `or` 'small' `or` 'medium' `or` 'large' `or` 'xl' `or` 'xxl' `or` 'xxxl' | | -| htmlType |当 component = 'button' 时,设置 button 标签的 type 值 | 'submit' `or` 'reset' `or` 'button' | | -| component |设置标签类型 | 'button' `or` 'a' | | -| loading |设置按钮的载入状态 | boolean | | -| ghost |是否为幽灵按钮 | true `or` false `or` 'light' `or` 'dark' | | -| text |是否为文本按钮 | boolean | | -| warning |是否为警告按钮 | boolean | | -| disabled |是否禁用 | boolean | | -| onClick |点击按钮的回调 | (e: {}) => void | | -| href |在Button组件使用component属性值为a时有效,代表链接页面的URL | string | | -| target |在Button组件使用component属性值为a时有效,代表何处打开链接文档 | string | | - - - +| 参数 | 说明 | 类型 | 默认值 | +| :--------- | :------------------------------------------------------------------- | :--------------------------------------------------------------------------------------- | :----- | +| forceClear | 是否清空 | boolean | | +| validate | 是否触发校验 | boolean | | +| type | 按钮的类型 | 'primary' `or` 'secondary' `or` 'normal' | | +| size | 按钮的尺寸 | 'small' `or` 'medium' `or` 'large' | | +| iconSize | 按钮中 Icon 的尺寸,用于替代 Icon 的默认大小 | 'xxs' `or` 'xs' `or` 'small' `or` 'medium' `or` 'large' `or` 'xl' `or` 'xxl' `or` 'xxxl' | | +| htmlType | 当 component = 'button' 时,设置 button 标签的 type 值 | 'submit' `or` 'reset' `or` 'button' | | +| component | 设置标签类型 | 'button' `or` 'a' | | +| loading | 设置按钮的载入状态 | boolean | | +| ghost | 是否为幽灵按钮 | true `or` false `or` 'light' `or` 'dark' | | +| text | 是否为文本按钮 | boolean | | +| warning | 是否为警告按钮 | boolean | | +| disabled | 是否禁用 | boolean | | +| onClick | 点击按钮的回调 | (e: {}) => void | | +| href | 在 Button 组件使用 component 属性值为 a 时有效,代表链接页面的 URL | string | | +| target | 在 Button 组件使用 component 属性值为 a 时有效,代表何处打开链接文档 | string | | **用法** 简单实例 ```jsx -import { createElement, useState } from 'rax'; -import View from 'rax-view'; -import { useLocale } from '@rax-ui/locale'; -import styles from './index.css'; -import { ConfigProvider } from '@alifd/meet'; +import { createElement, useState } from 'rax' +import View from 'rax-view' +import { useLocale } from '@rax-ui/locale' +import styles from './index.css' +import { ConfigProvider } from '@alifd/meet' -import { - SchemaForm, -} from '@formily/meet'; +import { SchemaForm } from '@formily/meet' -import { - setup, -} from '@formily/meet-components'; +import { setup } from '@formily/meet-components' -setup();//内部会完全按照Formily注册规则将组件注册一遍 +setup() //内部会完全按照Formily注册规则将组件注册一遍 const HomePage = () => { - return ( - + console.log(v)} onChange={v => console.log(v)} labelType="inner" schema={{ type: 'object', - + properties: { - content: { - type: "object", - "x-component": "formContent", + type: 'object', + 'x-component': 'formContent', properties: { input: { type: 'string', title: 'Password', - "x-rules": [{ - "required": true, - "message": "密码必填!" - }], - "x-component-props": { - "type": "password", - "clear": true, - 'align': 'left', - + 'x-rules': [ + { + required: true, + message: '密码必填!' + } + ], + 'x-component-props': { + type: 'password', + clear: true, + align: 'left' } }, username: { - "title": "Username", - "type": "string", - "x-rules": [{ - "required": true, - "message": "姓名字段必填!" - }], - "x-component-props": { - 'align': 'left', + title: 'Username', + type: 'string', + 'x-rules': [ + { + required: true, + message: '姓名字段必填!' + } + ], + 'x-component-props': { + align: 'left' } - }, gutter1: { - type: "object", - "x-component": "gutter", - "x-component-props": { + type: 'object', + 'x-component': 'gutter', + 'x-component-props': { style: { height: 100 } } }, date: { - "title": "Date", - "type": "date", - "x-component-props": { - "type": "datetime", - "selectSecond": true + title: 'Date', + type: 'date', + 'x-component-props': { + type: 'datetime', + selectSecond: true } }, gutter2: { - type: "object", - "x-component": "gutter", - "x-component-props": { + type: 'object', + 'x-component': 'gutter', + 'x-component-props': { style: { height: 40 } } }, select: { - "title": "Normal Select", - "type": "select", + title: 'Normal Select', + type: 'select', picker: 'radio', - "x-component-props": { - 'data': data, - 'type': 'multiple', - 'placeholder': "Please Sele5678ct..." + 'x-component-props': { + data: data, + type: 'multiple', + placeholder: 'Please Sele5678ct...' } }, select2: { - "title": "Format Label", - "type": "select", - "x-component-props": { - 'data': province, - 'type': 'cascade', - 'placeholder': "Please Select", - 'delimiter': ' / ', + title: 'Format Label', + type: 'select', + 'x-component-props': { + data: province, + type: 'cascade', + placeholder: 'Please Select', + delimiter: ' / ' } }, - - boolean: { - "title": "Switch", - "type": "boolean", - "x-component-props": { - 'checked': 'true', - styles: { + boolean: { + title: 'Switch', + type: 'boolean', - } + 'x-component-props': { + checked: 'true', + styles: {} }, - 'styles': { - 'text-align': 'left', - + styles: { + 'text-align': 'left' } }, textArea: { - "title": "Textarea", - "type": "string", - "x-component-props": { - "placeholder": "this is textArea", - "multiline": true, - "rows": 3, - }, + title: 'Textarea', + type: 'string', + 'x-component-props': { + placeholder: 'this is textArea', + multiline: true, + rows: 3 + } }, number: { type: 'number', title: 'Number', - "x-component-props": { + 'x-component-props': { min: 0, max: 100, tooltipVisible: false, styles: { 'number-picker__button': { height: '30px', - width: '30px', + width: '30px' }, 'number-picker__input': { height: '30px', - width: '60px', + width: '60px' } } } @@ -305,22 +300,26 @@ const HomePage = () => { checkbox: { type: 'checkbox', title: 'Checkbox', - "x-component-props": { - "data": [{ - label: 'checkbox 1', - value: '1' - }, { - label: 'checkbox 2', - value: '2', - disabled: true - }, { - label: 'checkbox 3', - value: '3' - }], + 'x-component-props': { + data: [ + { + label: 'checkbox 1', + value: '1' + }, + { + label: 'checkbox 2', + value: '2', + disabled: true + }, + { + label: 'checkbox 3', + value: '3' + } + ], styles: { 'number-picker__input': { height: '30px', - width: '60px', + width: '60px' } } } @@ -328,7 +327,7 @@ const HomePage = () => { range: { type: 'range', title: 'Range', - "x-component-props": { + 'x-component-props': { tooltipVisible: false, step: 0.01, max: 100, @@ -340,99 +339,93 @@ const HomePage = () => { style: { marginBottom: '25px', marginRight: '10px', - width: 320, - }, + width: 320 + } } }, radio: { type: 'radio', title: 'Radio', required: 'true', - "x-component-props": { - "data": radioData, - "direction": "horizontal", + 'x-component-props': { + data: radioData, + direction: 'horizontal', styles: { - 'radio__circle': { + radio__circle: { borderColor: 'red', - borderWidth: '2px', - }, - + borderWidth: '2px' + } } } - }, - }, + } + } }, footer: { - type: "object", - "x-component": "formFooter", - "x-component-props": { + type: 'object', + 'x-component': 'formFooter', + 'x-component-props': { style: { - 'form__footer': { + form__footer: { display: 'block', color: 'red' } - }, - + } }, - "properties": { + properties: { submit: { - type: "object", - "x-component": "submit", - "x-component-props": { - children: "提交", + type: 'object', + 'x-component': 'submit', + 'x-component-props': { + children: '提交', style: { width: '160px', - marginRight: '25px', + marginRight: '25px' }, styles: { - 'button': { - background: '#5050e6', + button: { + background: '#5050e6' }, - 'button__text': { + button__text: { color: '#ffffff' } } - }, + } }, reset: { - type: "object", - "x-component": "reset", - "x-component-props": { - children: "重置", + type: 'object', + 'x-component': 'reset', + 'x-component-props': { + children: '重置', style: { width: '160px', - marginTop: '10px', + marginTop: '10px' }, styles: { - 'button__text': { + button__text: { color: '#5050e6' } } - }, - }, - }, - }, + } + } + } + } } }} - > - - + > - - - ); + + ) } -render(, null, { driver: DriverUniversal }); - +render(, null, { driver: DriverUniversal }) ``` ### Hook #### `useFormTableQuery` -* 调用 useFormTableQuery 会返回 Table 和 Form 属性,只需简单传递给对应组件即可 -* useFormTableQuery 的传入参数是一个返回 Promise 对象的函数,该函数约定了它的出入参形式,如果接口请求出入参不符合这个约定,需要手动转换。 +- 调用 useFormTableQuery 会返回 Table 和 Form 属性,只需简单传递给对应组件即可 +- useFormTableQuery 的传入参数是一个返回 Promise 对象的函数,该函数约定了它的出入参形式,如果接口请求出入参不符合这个约定,需要手动转换。 ```typescript const useFormTableQuery = ( @@ -441,11 +434,9 @@ const useFormTableQuery = ( ) ``` - - #### `useFormState` -使用 useFormState 为自定义组件提供FormState扩展和管理能力 +使用 useFormState 为自定义组件提供 FormState 扩展和管理能力 **签名** @@ -471,16 +462,22 @@ import { setup } from '@formily/meet-components' setup() const actions = createFormActions() -const FormFragment = createVirtualBox('fusestatform', (props) => { +const FormFragment = createVirtualBox('fusestatform', props => { const [formState, setFormState] = useFormState({ extendVar: 0 }) const { extendVar } = formState - return
- -
count: {extendVar}
-
+ return ( +
+ +
count: {extendVar}
+
+ ) }) const App = () => { @@ -491,15 +488,13 @@ const App = () => { ) } -render(, null, { driver: DriverUniversal }); +render(, null, { driver: DriverUniversal }) ``` - - #### useForm -* 创建一个 [IForm](#IForm) 实例。需要注意的是,该操作会代理整个表单创建过程,包括actions的处理。 -* useForm是底层方法,它在包装具有业务属性的表单框架时非常有用。 +- 创建一个 [IForm](#IForm) 实例。需要注意的是,该操作会代理整个表单创建过程,包括 actions 的处理。 +- useForm 是底层方法,它在包装具有业务属性的表单框架时非常有用。 **签名** @@ -514,10 +509,9 @@ type useForm = < ) => IForm ``` - ### API -> 整体完全继承@formily/react,编译时对react进行转换为rax, 下面只列举@formily/meet 的特有 API +> 整体完全继承@formily/react,编译时对 react 进行转换为 rax, 下面只列举@formily/meet 的特有 API --- @@ -618,32 +612,31 @@ const App = () => { } ``` - #### connect -> 包装字段组件,让字段组件只需要支持value/defaultValue/onChange属性即可快速接入表单 +> 包装字段组件,让字段组件只需要支持 value/defaultValue/onChange 属性即可快速接入表单 ```typescript -type Connect = >(options?: IConnectOptions) => -(Target: T) => React.PureComponent +type Connect = >( + options?: IConnectOptions +) => (Target: T) => React.PureComponent ``` -* IConnectOptions - -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| valueName | value字段的名称 | string | `'value'` | -| eventName | 改变value的事件名 | string | `'onChange'` | -| defaultProps | 默认属性 | {} | {} | -| getValueFromEvent | 根据事件获取value | (event?: any, value?: any) => any | | -| getProps | 获取props的函数 | (componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => {} | void | | -| getComponent | 获取Component的函数 | (Target: any, componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => React.JSXElementConstructor | | +- IConnectOptions +| 参数 | 说明 | 类型 | 默认值 | +| :---------------- | :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------- | :----------- | +| valueName | value 字段的名称 | string | `'value'` | +| eventName | 改变 value 的事件名 | string | `'onChange'` | +| defaultProps | 默认属性 | {} | {} | +| getValueFromEvent | 根据事件获取 value | (event?: any, value?: any) => any | | +| getProps | 获取 props 的函数 | (componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => {} | void | | +| getComponent | 获取 Component 的函数 | (Target: any, componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => React.JSXElementConstructor | | **用法** ```typescript -import {registerFormField,connect} from '@formily/meet' +import { registerFormField, connect } from '@formily/meet' registerFormField( 'string', @@ -658,6 +651,7 @@ registerFormField( ```typescript function registerFormFields(object: ISchemaFormRegistry['fields']) ``` + **用法** ```jsx @@ -671,10 +665,20 @@ import { } from '@formily/meet' // 或者 @formily/next const CustomComponent1 = props => { - return props.onChange(e.target.value)} /> + return ( + props.onChange(e.target.value)} + /> + ) } const CustomComponent2 = props => { - return props.onChange(e.target.value)} + /> + ) } registerFormFields({ @@ -685,8 +689,16 @@ registerFormFields({ const App = () => { return ( - - + + ) } @@ -696,7 +708,7 @@ ReactDOM.render(, document.getElementById('root')) #### registerFormComponent -全局扩展 `` UI组件 +全局扩展 `` UI 组件 ```typescript function registerFormComponent( @@ -709,7 +721,11 @@ function registerFormComponent( ```tsx import React from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, SchemaMarkupField as Field, registerFormComponent } from '@formily/meet' +import { + SchemaForm, + SchemaMarkupField as Field, + registerFormComponent +} from '@formily/meet' import { Input } from '@formily/meet-components' registerFormComponent(props => { @@ -732,9 +748,7 @@ ReactDOM.render(, document.getElementById('root')) 全局扩展 `` UI 组件 ```typescript -function registerFormItemComponent( - component: React.JSXElementConstructor -) +function registerFormItemComponent(component: React.JSXElementConstructor) ``` **用法** @@ -742,7 +756,11 @@ function registerFormItemComponent( ```tsx import React from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, SchemaMarkupField as Field, registerFormItemComponent } from '@formily/meet' +import { + SchemaForm, + SchemaMarkupField as Field, + registerFormItemComponent +} from '@formily/meet' import { Input } from '@formily/meet-components' registerFormItemComponent(props => { @@ -760,7 +778,6 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - #### registerFormField ```typescript @@ -774,8 +791,12 @@ type registerFormField( **用法** ```tsx - -import SchemaForm, { SchemaMarkupField as Field, registerFormField, connect, createFormActions } from '@formily/meet' +import SchemaForm, { + SchemaMarkupField as Field, + registerFormField, + connect, + createFormActions +} from '@formily/meet' registerFormField( 'custom-string', @@ -785,7 +806,7 @@ const actions = createFormActions() const App = () => { return ( - + ) @@ -808,23 +829,28 @@ function createControllerBox( **用法** ```jsx - -import SchemaForm, { SchemaMarkupField as Field, createControllerBox, createFormActions } from '@formily/meet' +import SchemaForm, { + SchemaMarkupField as Field, + createControllerBox, + createFormActions +} from '@formily/meet' import { Input } from '@formily/meet-components' -const FormLayout = createControllerBox('controller-form-layout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+const FormLayout = createControllerBox('controller-form-layout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) const App = () => { return ( - + - + ) } @@ -846,25 +872,32 @@ function createVirtualBox( **用法** ```jsx - -import SchemaForm, { SchemaMarkupField as Field, createVirtualBox, createFormActions } from '@formily/meet' +import SchemaForm, { + SchemaMarkupField as Field, + createVirtualBox, + createFormActions +} from '@formily/meet' import { Input } from '@formily/meet-components' -const FormLayout = createVirtualBox('form-layout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+const FormLayout = createVirtualBox('form-layout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) const App = () => { return ( - - + + - + ) } @@ -886,20 +919,25 @@ function registerVirtualBox( **用法** ```jsx - -import SchemaForm, { SchemaMarkupField as Field, registerVirtualBox, createFormActions } from '@formily/meet' +import SchemaForm, { + SchemaMarkupField as Field, + registerVirtualBox, + createFormActions +} from '@formily/meet' import { Input } from '@formily/meet-components' -registerVirtualBox('form-layout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+registerVirtualBox('form-layout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) const App = () => { return ( - + { }} > - + ) } @@ -938,14 +976,18 @@ function getRegistry () => ISchemaFormRegistry **用法** ```tsx +import SchemaForm, { + SchemaMarkupField as Field, + getRegistry +} from '@formily/meet' -import SchemaForm, { SchemaMarkupField as Field, getRegistry } from '@formily/meet' - -registerVirtualBox('CustomLayout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+registerVirtualBox('CustomLayout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) getRegistry() @@ -956,20 +998,24 @@ getRegistry() 清理预先注册的所有组件。 ```typescript -function cleanRegistry () +function cleanRegistry() ``` **用法** ```tsx +import SchemaForm, { + SchemaMarkupField as Field, + cleanRegistry +} from '@formily/meet' -import SchemaForm, { SchemaMarkupField as Field, cleanRegistry } from '@formily/meet' - -registerVirtualBox('CustomLayout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+registerVirtualBox('CustomLayout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) cleanRegistry() @@ -1044,7 +1090,6 @@ interface ISchema { } ``` - #### IFormActions ```typescript @@ -1090,7 +1135,7 @@ interface IFormActions { //重置范围,用于批量或者精确控制要重置的字段 selector?: FormPathPattern //是否清空默认值 - clearInitialValue?:boolean + clearInitialValue?: boolean }): Promise /* @@ -1220,7 +1265,7 @@ interface IFormAsyncActions { //重置范围,用于批量或者精确控制要重置的字段 selector?: FormPathPattern //是否清空默认值 - clearInitialValue?:boolean + clearInitialValue?: boolean }): Promise /* * 获取状态变化情况,主要用于在表单生命周期钩子内判断当前生命周期中有哪些状态发生了变化, @@ -1291,7 +1336,6 @@ interface IFormAsyncActions { } ``` - #### ButtonProps ```typescript @@ -1373,7 +1417,6 @@ interface ISchemaFieldAdaptorProps } ``` - #### IFieldState ```typescript @@ -1438,7 +1481,6 @@ interface IFieldState { } ``` - #### ISchemaFieldComponentProps ```typescript @@ -1513,7 +1555,6 @@ interface ISchemaFormRegistry { } ``` - #### InternalFormats ```typescript @@ -1610,23 +1651,25 @@ interface IPreviewTextProps { innerAfter?: React.ReactNode addonAfter?: React.ReactNode } - ``` #### IMutators ```typescript interface IMutators { - change: (value: V)=> void,//改变当前字段值 - dispatch: (name: string, payload : any) => void,//触发effect事件 - errors: (errors: string | Array, ...formatValues: Array) => void,//设置当前字段的错误消息 - push(value: V),//对当前字段的值做push操作 - pop(),//对当前字段的值做pop操作 - insert(index: number,value: V),//对当前字段的值做insert操作 - remove(name : string),//对当前字段的值做remove操作 - unshift(value : V),//对当前字段值做unshift操作 - shift(),//对当前字段值做shift操作 - move(fromIndex: number, toIndex: number)//对当前字段值做move操作 + change: (value: V) => void //改变当前字段值 + dispatch: (name: string, payload: any) => void //触发effect事件 + errors: ( + errors: string | Array, + ...formatValues: Array + ) => void //设置当前字段的错误消息 + push(value: V) //对当前字段的值做push操作 + pop() //对当前字段的值做pop操作 + insert(index: number, value: V) //对当前字段的值做insert操作 + remove(name: string) //对当前字段的值做remove操作 + unshift(value: V) //对当前字段值做unshift操作 + shift() //对当前字段值做shift操作 + move(fromIndex: number, toIndex: number) //对当前字段值做move操作 } ``` @@ -1634,26 +1677,32 @@ interface IMutators { ```typescript interface IFieldProps { - name : string //字段数据路径 - path : Array //字段数组数据路径 - value : V //字段值 - errors : Array //字段错误消息集合 - editable : boolean | ((name:string) => boolean) //字段是否可编辑 - locale : Locale //国际化文案对象 - loading : boolean //是否处于加载态 - schemaPath : Array //schema path,考虑到有些schema其实是不占数据路径的,所以这个路径是真实路径 - getSchema : (path: string) => ISchema //根据路径获取schema - renderField : (childKey: string, reactKey: string | number) => JSX.Element | string | null //根据childKey渲染当前字段的子字段 - renderComponent : React.FunctionComponent | undefined>,//渲染当前字段的组件,对于x-render来说,可以借助它快速实现渲染包装功能 - getOrderProperties : () => Array<{schema: ISchema, key: number, path: string, name: string }>,//根据properties里字段的x-index值求出排序后的properties - mutators : Mutators,//数据操作对象 - schema : ISchema + name: string //字段数据路径 + path: Array //字段数组数据路径 + value: V //字段值 + errors: Array //字段错误消息集合 + editable: boolean | ((name: string) => boolean) //字段是否可编辑 + locale: Locale //国际化文案对象 + loading: boolean //是否处于加载态 + schemaPath: Array //schema path,考虑到有些schema其实是不占数据路径的,所以这个路径是真实路径 + getSchema: (path: string) => ISchema //根据路径获取schema + renderField: ( + childKey: string, + reactKey: string | number + ) => JSX.Element | string | null //根据childKey渲染当前字段的子字段 + renderComponent: React.FunctionComponent | undefined> //渲染当前字段的组件,对于x-render来说,可以借助它快速实现渲染包装功能 + getOrderProperties: () => Array<{ + schema: ISchema + key: number + path: string + name: string + }> //根据properties里字段的x-index值求出排序后的properties + mutators: Mutators //数据操作对象 + schema: ISchema } - ``` ```typescript - interface IConnectOptions { //控制表单组件 valueName?: string @@ -1662,20 +1711,25 @@ interface IConnectOptions { //默认props defaultProps?: Partial //取值函数,有些场景我们的事件函数取值并不是事件回调的第一个参数,需要做进一步的定制 - getValueFromEvent?: (props: IFieldProps['x-props'], event: Event, ...args: any[]) => any + getValueFromEvent?: ( + props: IFieldProps['x-props'], + event: Event, + ...args: any[] + ) => any //字段组件props transformer - getProps?: (connectProps: IConnectProps, fieldProps: IFieldProps) => IConnectProps + getProps?: ( + connectProps: IConnectProps, + fieldProps: IFieldProps + ) => IConnectProps //字段组件component transformer - getComponent?: ( - target: T, + getComponent?: ( + target: T, connectProps: IConnectProps, fieldProps: IFieldProps ) => T } - ``` - ### IForm ```typescript @@ -1749,21 +1803,20 @@ interface IFormActions { setFieldInitialValue(path?: FormPathPattern, value?: any): void getFieldInitialValue(path?: FormPathPattern): any } - ``` #### IFormValidateResult ```typescript interface IFormValidateResult { - errors: Array<{ - path: string; - messages: string[]; - }>; - warnings: Array<{ - path: string; - messages: string[]; - }>; + errors: Array<{ + path: string + messages: string[] + }> + warnings: Array<{ + path: string + messages: string[] + }> } ``` @@ -1820,7 +1873,6 @@ interface MergedFieldComponentProps extends IFieldState { reactKey?: string | number ) => React.ReactElement } - ``` #### Pagination diff --git a/packages/next-components/README.zh-cn.md b/packages/next-components/README.zh-cn.md index 322b7fa0993..f6a11c8c9f7 100644 --- a/packages/next-components/README.zh-cn.md +++ b/packages/next-components/README.zh-cn.md @@ -8,27 +8,25 @@ npm install --save @formily/next-components ### 显式加载组件 -通过在``传入components,可以快速置入组件,表单字段通过`x-component`使用到内置的组件。 +通过在``传入 components,可以快速置入组件,表单字段通过`x-component`使用到内置的组件。 ```tsx -import { SchemaForm, SchemaMarkupField as Field, FormButtonGroup, Submit } from '@formily/next' +import { + SchemaForm, + SchemaMarkupField as Field, + FormButtonGroup, + Submit +} from '@formily/next' import { Input } from '@formily/next-components' import '@alifd/next/dist/next.css' export default () => { return ( - - + + ) } - ``` ### 使用内置组件 @@ -36,7 +34,12 @@ export default () => { 通过 `setup` 方法,可以快速置入内置的表单组件,免去维护全局`components`的工作。 ```tsx -import { SchemaForm, SchemaMarkupField as Field, FormButtonGroup, Submit } from '@formily/next' +import { + SchemaForm, + SchemaMarkupField as Field, + FormButtonGroup, + Submit +} from '@formily/next' import { setup } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -44,49 +47,40 @@ setup() export default () => { return ( - + ) } - ``` ### 内置组件类型 通过 `setup`后,内置的表单字段有以下类型 -| type类型 | 对应组件 | 描述 | -|:--------------|:----------------------------------|:----------------------| -| string | [Input](#Input) | 输入框组件 | -| string(有enum属性时) | [Select](#Select) | 选择框组件 | -| textarea | [Textarea](#Textarea) | 多行输入框组件 | -| password | [Password](#Password) | 密码输入框 | -| checkbox | [CheckboxGroup](#Checkbox) | Checkbox | -| radio | [RadioGroup](#Radio) | Radio | -| boolean | [Switch](#Swicth) | 开关组件 | -| date | [DatePicker](#DatePicker) | 日期选择器 | -| time | [TimePicker](#TimePicker) | 时间选择器 | -| daterange | [DatePicker.RangePicker](#RangePicker) | 范围日期选择器 | -| rating | [Rating](#Rating) | 评价组件 | -| object | | 嵌套表单 | 自动连接路径信息 -| array | [ArrayCards](#ArrayCards)(默认) | 表单数组 | 表单数组 - +| type 类型 | 对应组件 | 描述 | +| :--------------------- | :------------------------------------- | :------------- | +| string | [Input](#Input) | 输入框组件 | +| string(有 enum 属性时) | [Select](#Select) | 选择框组件 | +| textarea | [Textarea](#Textarea) | 多行输入框组件 | +| password | [Password](#Password) | 密码输入框 | +| checkbox | [CheckboxGroup](#Checkbox) | Checkbox | +| radio | [RadioGroup](#Radio) | Radio | +| boolean | [Switch](#Swicth) | 开关组件 | +| date | [DatePicker](#DatePicker) | 日期选择器 | +| time | [TimePicker](#TimePicker) | 时间选择器 | +| daterange | [DatePicker.RangePicker](#RangePicker) | 范围日期选择器 | +| rating | [Rating](#Rating) | 评价组件 | +| object | | 嵌套表单 | 自动连接路径信息 | +| array | [ArrayCards](#ArrayCards)(默认) | 表单数组 | 表单数组 | #### Input -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Input } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -94,7 +88,7 @@ const App = () => { return ( { 'x-component': 'Input', 'x-component-props': { placeholder: 'input' - }, - }, + } + } } }} - > - - + > ) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -125,7 +117,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Input } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -134,7 +126,7 @@ const App = () => { return ( { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - Form, - FormItem, -} from '@formily/next' +import { Form, FormItem } from '@formily/next' import { Input } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -178,15 +167,12 @@ ReactDOM.render(, document.getElementById('root')) #### Select -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Select } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -194,7 +180,7 @@ const App = () => { return ( { 'x-component': 'Select', 'x-component-props': { placeholder: 'select' - }, + } }, objSelect: { title: 'Object Select', @@ -218,20 +204,18 @@ const App = () => { ], 'x-component-props': { placeholder: 'select' - }, - }, + } + } } }} - > - - + > ) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -239,7 +223,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Select } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -248,7 +232,7 @@ const App = () => { return ( { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - Form, - FormItem, -} from '@formily/next' +import { Form, FormItem } from '@formily/next' import { Select } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - - { ReactDOM.render(, document.getElementById('root')) ``` - #### TextArea -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Input } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -345,20 +328,18 @@ const App = () => { 'x-component': 'TextArea', 'x-component-props': { placeholder: 'textarea' - }, - }, + } + } } }} - > - - + > ) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -366,16 +347,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Input } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -401,9 +380,11 @@ import { Input } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return ( - - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -411,15 +392,12 @@ ReactDOM.render(, document.getElementById('root')) #### Password -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Password } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -437,20 +415,18 @@ const App = () => { 'x-component': 'Password', 'x-component-props': { placeholder: 'Password' - }, - }, + } + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -458,16 +434,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Password } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -493,9 +467,11 @@ import { Password } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -503,15 +479,12 @@ ReactDOM.render(, document.getElementById('root')) #### NumberPicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { NumberPicker } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -526,20 +499,18 @@ const App = () => { properties: { textarea: { title: 'NumberPicker', - 'x-component': 'NumberPicker', - }, + 'x-component': 'NumberPicker' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -547,16 +518,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { NumberPicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -579,26 +548,28 @@ import { NumberPicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) ``` - #### Switch -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Switch } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -613,20 +584,18 @@ const App = () => { properties: { textarea: { title: 'Switch', - 'x-component': 'Switch', - }, + 'x-component': 'Switch' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -634,21 +603,15 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Switch } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - - + + ) } @@ -656,7 +619,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -666,9 +629,11 @@ import { Switch } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -676,15 +641,12 @@ ReactDOM.render(, document.getElementById('root')) #### DatePicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -702,20 +664,18 @@ const App = () => { 'x-component': 'DatePicker', 'x-component-props': { format: 'YYYY-MM-DD HH:mm:ss' - }, - }, + } + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -723,16 +683,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -758,9 +716,16 @@ import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -768,7 +733,7 @@ ReactDOM.render(, document.getElementById('root')) #### RangePicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' @@ -776,7 +741,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -792,20 +757,18 @@ const App = () => { properties: { '[start,end]': { title: 'RangePicker', - 'x-component': 'RangePicker', - }, + 'x-component': 'RangePicker' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -813,21 +776,15 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - - + + ) } @@ -835,7 +792,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -845,9 +802,15 @@ import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -855,15 +818,12 @@ ReactDOM.render(, document.getElementById('root')) #### WeekPicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -878,20 +838,18 @@ const App = () => { properties: { textarea: { title: 'WeekPicker', - 'x-component': 'WeekPicker', - }, + 'x-component': 'WeekPicker' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -899,21 +857,15 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - - + + ) } @@ -921,7 +873,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -931,9 +883,15 @@ import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -941,15 +899,12 @@ ReactDOM.render(, document.getElementById('root')) #### MonthPicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -964,20 +919,18 @@ const App = () => { properties: { textarea: { title: 'MonthPicker', - 'x-component': 'MonthPicker', - }, + 'x-component': 'MonthPicker' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -985,21 +938,15 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - - + + ) } @@ -1007,7 +954,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1017,9 +964,15 @@ import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1027,15 +980,12 @@ ReactDOM.render(, document.getElementById('root')) #### YearPicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1050,20 +1000,18 @@ const App = () => { properties: { textarea: { title: 'YearPicker', - 'x-component': 'YearPicker', - }, + 'x-component': 'YearPicker' + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1071,21 +1019,15 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - - + + ) } @@ -1093,7 +1035,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1103,9 +1045,15 @@ import { DatePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1113,15 +1061,12 @@ ReactDOM.render(, document.getElementById('root')) #### TimePicker -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { TimePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1139,20 +1084,18 @@ const App = () => { 'x-component': 'TimePicker', 'x-component-props': { format: 'YYYY-MM-DD HH:mm:ss' - }, - }, + } + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1160,16 +1103,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { TimePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1195,9 +1136,11 @@ import { TimePicker } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1205,15 +1148,12 @@ ReactDOM.render(, document.getElementById('root')) #### Range -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Range } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1234,19 +1174,17 @@ const App = () => { max: 1024, marks: [0, 1024] } - }, + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1254,16 +1192,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Range } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1291,14 +1227,18 @@ import { Range } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1306,15 +1246,12 @@ ReactDOM.render(, document.getElementById('root')) #### Upload -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Upload } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1347,19 +1284,17 @@ const App = () => { 'x-component-props': { listType: 'text' } - }, + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1367,16 +1302,14 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Upload } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { return ( - + { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1418,20 +1351,28 @@ import { Upload } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - - - ) + return ( +
+ + + + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1439,15 +1380,12 @@ ReactDOM.render(, document.getElementById('root')) #### Checkbox -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Checkbox } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1456,7 +1394,7 @@ const App = () => { { { label: 'Three', value: '3' }, { label: 'Four', value: '4' } ] - }, + } } }} - > - - + >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1495,7 +1431,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Checkbox } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1505,7 +1441,7 @@ const App = () => { { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1542,21 +1478,27 @@ import { Checkbox } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - + + - ) + /> + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1564,15 +1506,12 @@ ReactDOM.render(, document.getElementById('root')) #### Radio -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Radio } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1581,7 +1520,7 @@ const App = () => { { { label: 'Three', value: '3' }, { label: 'Four', value: '4' } ] - }, + } } }} - > - - + >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1620,7 +1557,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Radio } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1630,7 +1567,7 @@ const App = () => { { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1667,21 +1604,27 @@ import { Radio } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - + + - ) + /> + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1689,15 +1632,12 @@ ReactDOM.render(, document.getElementById('root')) #### Rating -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Rating } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1716,19 +1656,17 @@ const App = () => { 'x-component-props': { allowHalf: true } - }, + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1736,7 +1674,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Rating } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1763,7 +1701,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1773,12 +1711,11 @@ import { Rating } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1786,15 +1723,12 @@ ReactDOM.render(, document.getElementById('root')) #### Transfer -* JSON Schema 方式 +- JSON Schema 方式 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { - SchemaForm, - SchemaMarkupField as Field, -} from '@formily/next' +import { SchemaForm, SchemaMarkupField as Field } from '@formily/next' import { Transfer } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1819,19 +1753,17 @@ const App = () => { 'x-component-props': { showSearch: true } - }, + } } }} - > - -
+ >
) } ReactDOM.render(, document.getElementById('root')) ``` -* JSX Schema 方式 +- JSX Schema 方式 ```jsx import React from 'react' @@ -1839,7 +1771,7 @@ import ReactDOM from 'react-dom' import { SchemaForm, SchemaMarkupField as Field, - createFormActions, + createFormActions } from '@formily/next' import { Transfer } from '@formily/next-components' import '@alifd/next/dist/next.css' @@ -1872,7 +1804,7 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -* 纯 JSX(源码) 方式 +- 纯 JSX(源码) 方式 ```jsx import React from 'react' @@ -1882,18 +1814,22 @@ import { Transfer } from '@formily/next-components' import '@alifd/next/dist/next.css' const App = () => { - return (
- - ) + return ( +
+ + + ) } ReactDOM.render(, document.getElementById('root')) @@ -1908,11 +1844,12 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, - Field, +import { + SchemaForm, + Field, FormButtonGroup, Submit, - Reset, + Reset } from '@formily/next' import { Input, @@ -1920,7 +1857,8 @@ import { DatePicker, FormBlock, FormItemGrid, - FormLayout } from '@formily/next-components' + FormLayout +} from '@formily/next-components' import '@alifd/next/dist/next.css' import Printer from '@formily/printer' @@ -1930,7 +1868,7 @@ const App = () => ( components={{ Input, ArrayCards, - RangePicker: DatePicker.RangePicker, + RangePicker: DatePicker.RangePicker }} > , document.getElementById('root')) ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, - Field, +import { + SchemaForm, + Field, FormButtonGroup, Submit, - Reset, + Reset } from '@formily/next' import { Input, @@ -2010,7 +1949,8 @@ import { DatePicker, FormBlock, FormItemGrid, - FormLayout } from '@formily/next-components' + FormLayout +} from '@formily/next-components' import '@alifd/next/dist/next.css' import Printer from '@formily/printer' @@ -2020,7 +1960,7 @@ const App = () => ( components={{ ArrayTable, Input, - RangePicker: DatePicker.RangePicker, + RangePicker: DatePicker.RangePicker }} > @@ -2062,11 +2002,10 @@ ReactDOM.render(, document.getElementById('root')) ### Layout Components - #### FormCard > FormCard 组件 Props, 完全继承自 [CardProps](#CardProps)。 -> FormCard与[FormBlock](#FormBlock) 唯一区别是样式上是否有框 +> FormCard 与[FormBlock](#FormBlock) 唯一区别是样式上是否有框 **用法** @@ -2114,19 +2053,18 @@ ReactDOM.render(, document.getElementById('root')) > FormStep 组件 Props -* IFormStep - -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| dataSource | 分步配置 | StepItemProps[] | | -| current | 当前步骤 | number | | -| direction | 展示方向 | 'hoz' `or` 'ver' | | -| labelPlacement | 横向布局时的内容排列 | 'hoz' `or` 'ver' | | -| shape | 类型 | 'circle' `or` 'arrow' `or` 'dot' | | -| readOnly | 是否只读模式 | boolean | | -| animation | 是否开启动效 | boolean | | -| itemRender | StepItem 的自定义渲染 | (index: number, status: string) => React.ReactNode | | +- IFormStep +| 参数 | 说明 | 类型 | 默认值 | +| :------------- | :-------------------- | :------------------------------------------------- | :----- | +| dataSource | 分步配置 | StepItemProps[] | | +| current | 当前步骤 | number | | +| direction | 展示方向 | 'hoz' `or` 'ver' | | +| labelPlacement | 横向布局时的内容排列 | 'hoz' `or` 'ver' | | +| shape | 类型 | 'circle' `or` 'arrow' `or` 'dot' | | +| readOnly | 是否只读模式 | boolean | | +| animation | 是否开启动效 | boolean | | +| itemRender | StepItem 的自定义渲染 | (index: number, status: string) => React.ReactNode | | **用法** @@ -2142,7 +2080,7 @@ import { createFormActions, Reset } from '@formily/next' -import { +import { Input, FormGridRow, FormItemGrid, @@ -2229,7 +2167,6 @@ export default () => ( ) ``` - #### FormTab ```jsx @@ -2301,11 +2238,15 @@ const App = () => ( - + - - - ) - })} - -
) - }} - + + {({ state, mutators }) => { + const onAdd = () => mutators.push() + return ( +
+ {state.value.map((item, index) => { + const onRemove = index => mutators.remove(index) + const onMoveUp = index => mutators.moveUp(index) + const onMoveDown = index => mutators.moveDown(index) + return ( + + + + + + + + ) + })} + +
+ ) + }} +
) } @@ -547,20 +579,19 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - #### `` -* IFormButtonGroupProps +- IFormButtonGroupProps -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| sticky |是否吸附在页面底部 | boolean | | -| itemStyle |每个Btn的样式 | React.CSSProperties | | -| align |对齐方式 | 'left' `or` 'right' `or` 'start' `or` 'end' `or` 'top' `or` 'bottom' `or` 'center' | | -| triggerDistance | 按钮间距离 | number | | -| zIndex | z-index | number | | -| span | 跨列配置 | number | string | | -| offset | 偏移配置 | number | string | | +| 参数 | 说明 | 类型 | 默认值 | +| :-------------- | :----------------- | :--------------------------------------------------------------------------------- | :----- | +| sticky | 是否吸附在页面底部 | boolean | | +| itemStyle | 每个 Btn 的样式 | React.CSSProperties | | +| align | 对齐方式 | 'left' `or` 'right' `or` 'start' `or` 'end' `or` 'top' `or` 'bottom' `or` 'center' | | +| triggerDistance | 按钮间距离 | number | | +| zIndex | z-index | number | | +| span | 跨列配置 | number | string | | +| offset | 偏移配置 | number | string | | **用法** @@ -574,7 +605,7 @@ import { FormButtonGroup, Reset } from '@formily/next' -import { +import { setup, FormItemGrid, FormCard, @@ -613,13 +644,12 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - ### Hook #### `useFormTableQuery` -* 调用 useFormTableQuery 会返回 Table 和 Form 属性,只需简单传递给对应组件即可 -* useFormTableQuery 的传入参数是一个返回 Promise 对象的函数,该函数约定了它的出入参形式,如果接口请求出入参不符合这个约定,需要手动转换。 +- 调用 useFormTableQuery 会返回 Table 和 Form 属性,只需简单传递给对应组件即可 +- useFormTableQuery 的传入参数是一个返回 Promise 对象的函数,该函数约定了它的出入参形式,如果接口请求出入参不符合这个约定,需要手动转换。 ```typescript const useFormTableQuery = ( @@ -628,20 +658,20 @@ const useFormTableQuery = ( ) ``` -* useFormTableQuery入参 +- useFormTableQuery 入参 -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| 参数1 |列表请求服务 | (payload: [IQueryParams](#IQueryParams)) => [IQueryResponse](#IQueryParams) | Promise<[IQueryResponse](#IQueryParams)> | | -| 参数2 |请求处理middlewares | IEffectMiddleware<[ISchemaFormActions](#IFormActions)> | | +| 参数 | 说明 | 类型 | 默认值 | +| :----- | :------------------- | :-------------------------------------------------------------------------- | :--------------------------------------- | +| 参数 1 | 列表请求服务 | (payload: [IQueryParams](#IQueryParams)) => [IQueryResponse](#IQueryParams) | Promise<[IQueryResponse](#IQueryParams)> | | +| 参数 2 | 请求处理 middlewares | IEffectMiddleware<[ISchemaFormActions](#IFormActions)> | | -* useFormTableQuery返回结果 +- useFormTableQuery 返回结果 -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| trigger |触发列表请求 | any | | -| form | Form属性,主要为effects | { effects: [IFormEffect](#IFormEffect) } | | -| table |Table属性 | { loading:boolean, dataSource: any[], pagination: [Pagination](#Pagination), onChange } | | +| 参数 | 说明 | 类型 | 默认值 | +| :------ | :------------------------ | :-------------------------------------------------------------------------------------- | :----- | +| trigger | 触发列表请求 | any | | +| form | Form 属性,主要为 effects | { effects: [IFormEffect](#IFormEffect) } | | +| table | Table 属性 | { loading:boolean, dataSource: any[], pagination: [Pagination](#Pagination), onChange } | | **用法** @@ -697,17 +727,23 @@ const App = () => { 重置
- record.login.uuid} - > - { - return `${val.first} ${val.last}` - }} /> - +
record.login.uuid}> + { + return `${val.first} ${val.last}` + }} + /> +
@@ -721,8 +757,8 @@ ReactDOM.render(, document.getElementById('root')) 通过使用 `useFormEffects` 可以轻松实现拥有局部逻辑表单。 -* 使用 useFormEffects 可以实现局部effect的表单组件,效果同:[简单联动](#简单联动) -* 注意:监听的生命周期是从 `ON_FORM_MOUNT` 开始 +- 使用 useFormEffects 可以实现局部 effect 的表单组件,效果同:[简单联动](#简单联动) +- 注意:监听的生命周期是从 `ON_FORM_MOUNT` 开始 **签名** @@ -751,45 +787,47 @@ import { setup } from '@formily/next-components' setup() const actions = createFormActions() -const FragmentContainer = createVirtualBox('ffb', (props) => { +const FragmentContainer = createVirtualBox('ffb', props => { useFormEffects(($, { setFieldState }) => { $(LifeCycleTypes.ON_FORM_MOUNT).subscribe(() => { - setFieldState('a~', state => state.visible = false) + setFieldState('a~', state => (state.visible = false)) }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((triggerState) => { - setFieldState('a~', state => { - state.visible = triggerState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe( + triggerState => { + setFieldState('a~', state => { + state.visible = triggerState.value + }) + } + ) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe((fieldState) => { + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe(fieldState => { setFieldState('a-copy', state => { state.value = fieldState.value }) }) }) - return ( - - {props.children} - - ) -}); - + return {props.children} +}) // 具有局部逻辑的表单 const FormFragment = () => { - return - - - - + return ( + + + + + + ) } const App = () => { @@ -805,7 +843,7 @@ ReactDOM.render(, document.getElementById('root')) #### `useFormState` -使用 useFormState 为自定义组件提供FormState扩展和管理能力 +使用 useFormState 为自定义组件提供 FormState 扩展和管理能力 **签名** @@ -831,16 +869,22 @@ import { setup } from '@formily/next-components' setup() const actions = createFormActions() -const FormFragment = createVirtualBox('fusestatform', (props) => { +const FormFragment = createVirtualBox('fusestatform', props => { const [formState, setFormState] = useFormState({ extendVar: 0 }) const { extendVar } = formState - return
- -
count: {extendVar}
-
+ return ( +
+ +
count: {extendVar}
+
+ ) }) const App = () => { @@ -871,26 +915,28 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, +import { + SchemaForm, SchemaMarkupField as Field, - createFormActions, createEffectHook, - useForm, + createFormActions, + createEffectHook, + useForm, useFormEffects, useFieldState, LifeCycleTypes, - createControllerBox, + createControllerBox } from '@formily/next' import { setup } from '@formily/next-components' setup() const changeTab$ = createEffectHook('changeTab') const actions = createFormActions() -const TabFragment = (props) => { - const [fieldState, setLocalFieldState ] = useFieldState({ current: 0 }) +const TabFragment = props => { + const [fieldState, setLocalFieldState] = useFieldState({ current: 0 }) const { current } = fieldState const { children, dataSource, form } = props - const update = (cur) => { + const update = cur => { form.notify('changeTab', cur) setLocalFieldState({ current: cur @@ -904,37 +950,47 @@ const TabFragment = (props) => { }) }) - changeTab$().subscribe((idx) => { + changeTab$().subscribe(idx => { dataSource.forEach((item, itemIdx) => { - setFieldState(item.name, state => { - state.display = itemIdx === idx + setFieldState(item.name, state => { + state.display = itemIdx === idx + }) }) }) - }) }) const btns = dataSource.map((item, idx) => { - const focusStyle = idx === current ? { color: '#fff', background: 'blue' } : {} - return + const focusStyle = + idx === current ? { color: '#fff', background: 'blue' } : {} + return ( + + ) }) return btns } -const FormTab = createControllerBox('formTab', (props) => { - const { form, props: comProps } = props; +const FormTab = createControllerBox('formTab', props => { + const { form, props: comProps } = props return }) const App = () => { return ( - +
@@ -948,8 +1004,8 @@ ReactDOM.render(, document.getElementById('root')) #### useForm -* 创建一个 [IForm](#IForm) 实例。需要注意的是,该操作会代理整个表单创建过程,包括actions的处理。 -* useForm是底层方法,它在包装具有业务属性的表单框架时非常有用。 +- 创建一个 [IForm](#IForm) 实例。需要注意的是,该操作会代理整个表单创建过程,包括 actions 的处理。 +- useForm 是底层方法,它在包装具有业务属性的表单框架时非常有用。 **签名** @@ -969,15 +1025,17 @@ type useForm = < ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, +import { + SchemaForm, SchemaMarkupField as Field, - createFormActions, createEffectHook, - useForm, + createFormActions, + createEffectHook, + useForm, FormSpy, useFormEffects, useFieldState, LifeCycleTypes, - createVirtualBox, + createVirtualBox } from '@formily/next' import { setup } from '@formily/next-components' @@ -986,7 +1044,7 @@ const actions = createFormActions() const App = () => { const form = useForm({ value: { username: 'moe' }, - actions, + actions }) return ( @@ -997,7 +1055,6 @@ const App = () => { } ReactDOM.render(, document.getElementById('root')) - ``` #### useField @@ -1015,30 +1072,29 @@ type useField = (options: IFieldStateUIProps): IFieldHook ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, +import { + SchemaForm, SchemaMarkupField as Field, - createFormActions, createEffectHook, - useForm, + createFormActions, + createEffectHook, + useForm, FormSpy, useFormEffects, LifeCycleTypes, createControllerBox, - useField, + useField } from '@formily/next' -const CustomField = createControllerBox('customField', (props) => { - const { name } = props; - const realName = props.props['x-component-props']['x-name']; - const { - form, - state, - props: fieldProps, - mutators - } = useField({ - name: `${name}.${realName}`, - }) - - return +const CustomField = createControllerBox('customField', props => { + const { name } = props + const realName = props.props['x-component-props']['x-name'] + const { form, state, props: fieldProps, mutators } = useField({ + name: `${name}.${realName}` + }) + + return ( + + ) }) const App = () => { @@ -1046,14 +1102,15 @@ const App = () => { - {({ state, form }) =>
name: {form && form.getFieldValue('username')}
} + {({ state, form }) => ( +
name: {form && form.getFieldValue('username')}
+ )}
) } ReactDOM.render(, document.getElementById('root')) - ``` #### useVirtualField @@ -1071,21 +1128,23 @@ type UseVirtualField = (options: IVirtualFieldStateProps): IVirtualFieldHook ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, +import { + SchemaForm, SchemaMarkupField as Field, - createFormActions, createEffectHook, - useForm, + createFormActions, + createEffectHook, + useForm, FormSpy, useFormEffects, LifeCycleTypes, createControllerBox, - useVirtualField, + useVirtualField } from '@formily/next' import { setup } from '@formily/next-components' setup() -const LayoutBox = createControllerBox('LayoutBox', (props) => { +const LayoutBox = createControllerBox('LayoutBox', props => { useVirtualField({ name: 'random' }) return
{props.children}
}) @@ -1096,13 +1155,12 @@ const App = () => { - + ) } ReactDOM.render(, document.getElementById('root')) - ``` #### useFormSpy @@ -1120,21 +1178,23 @@ type useFormSpy = (props: IFormSpyProps): ISpyHook ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, +import { + SchemaForm, SchemaMarkupField as Field, - createFormActions, createEffectHook, - useForm, + createFormActions, + createEffectHook, + useForm, FormSpy, useFormEffects, LifeCycleTypes, createControllerBox, - useFormSpy, + useFormSpy } from '@formily/next' import { setup } from '@formily/next-components' setup() -const CustomSpy = createControllerBox('CustomSpy', (props) => { +const CustomSpy = createControllerBox('CustomSpy', props => { const { form } = useFormSpy({ selector: '*', reducer: v => v }) return
name: {form && form.getFieldValue('username')}
}) @@ -1149,7 +1209,6 @@ const App = () => { } ReactDOM.render(, document.getElementById('root')) - ``` #### useDeepFormItem @@ -1161,7 +1220,7 @@ ReactDOM.render(, document.getElementById('root')) ```tsx import { useDeepFormItem, FormItemDeepProvider } from '@formily/next' import { Form } from '@alifd/next' -const CustomComponent = (props) => { +const CustomComponent = props => { const { prefixCls, labelAlign, @@ -1169,22 +1228,25 @@ const CustomComponent = (props) => { wrapperCol: contextWrapperCol } = useDeepFormItem() - return - {props.children} - + return ( + + {props.children} + + ) } const App = () => { - return - - + return ( + + + + ) } - ``` #### useShallowFormItem @@ -1193,7 +1255,7 @@ const App = () => { **用法** -下列 `` 除了`label`以外,会继承其他所有顶部的 `FormItem` 属性。 +下列 `` 除了`label`以外,会继承其他所有顶部的 `FormItem` 属性。 ```tsx import { SchemaField, FormItemShallowProvider, useShallowFormItem } from '@formily/next' @@ -1206,7 +1268,6 @@ const NoLabelInput = (props) => { ``` - ### API > 整体完全继承@formily/react, 下面只列举@formily/next 的特有 API @@ -1271,36 +1332,36 @@ setValidationLanguage('zh') #### setValidationLocale -设置校验规则命中时,message的定义, 搭配[setValidationLanguage](#setValidationLanguage) 使用 +设置校验规则命中时,message 的定义, 搭配[setValidationLanguage](#setValidationLanguage) 使用 **签名** ```typescript interface ILocaleMessages { - [key: string]: string | ILocaleMessages; + [key: string]: string | ILocaleMessages } interface ILocales { - [lang: string]: ILocaleMessages; + [lang: string]: ILocaleMessages } -const setValidationLocale: (locale: ILocales) => void; +const setValidationLocale: (locale: ILocales) => void ``` **用法** ```tsx -import { setValidationLanguage, setValidationLocale, } from '@formily/next' +import { setValidationLanguage, setValidationLocale } from '@formily/next' setValidationLanguage('zh') setValidationLocale({ zh: { - required: '这是修改默认的必填文案', - }, + required: '这是修改默认的必填文案' + } }) ``` #### registerValidationFormats -拓展校验正则format, 当不满足此规则时即报错。 +拓展校验正则 format, 当不满足此规则时即报错。 **签名** @@ -1348,8 +1409,8 @@ static (template: any) => void; import { setValidationLocale, registerValidationMTEngine } from '@formily/next' setValidationLocale({ en: { - required: '这是定制必填文案 <% injectVar %>', - }, + required: '这是定制必填文案 <% injectVar %>' + } }) registerValidationMTEngine((message, context) => { @@ -1471,29 +1532,29 @@ ReactDOM.render(, document.getElementById('root')) #### connect -> 包装字段组件,让字段组件只需要支持value/defaultValue/onChange属性即可快速接入表单 +> 包装字段组件,让字段组件只需要支持 value/defaultValue/onChange 属性即可快速接入表单 ```typescript -type Connect = >(options?: IConnectOptions) => -(Target: T) => React.PureComponent +type Connect = >( + options?: IConnectOptions +) => (Target: T) => React.PureComponent ``` -* IConnectOptions - -| 参数 | 说明 | 类型 | 默认值 | -|:----------|:---------------------------------|:--------------------|:--------------------| -| valueName | value字段的名称 | string | `'value'` | -| eventName | 改变value的事件名 | string | `'onChange'` | -| defaultProps | 默认属性 | {} | {} | -| getValueFromEvent | 根据事件获取value | (event?: any, value?: any) => any | | -| getProps | 获取props的函数 | (componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => {} | void | | -| getComponent | 获取Component的函数 | (Target: any, componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => React.JSXElementConstructor | | +- IConnectOptions +| 参数 | 说明 | 类型 | 默认值 | +| :---------------- | :-------------------- | :----------------------------------------------------------------------------------------------------------------------------------------- | :----------- | +| valueName | value 字段的名称 | string | `'value'` | +| eventName | 改变 value 的事件名 | string | `'onChange'` | +| defaultProps | 默认属性 | {} | {} | +| getValueFromEvent | 根据事件获取 value | (event?: any, value?: any) => any | | +| getProps | 获取 props 的函数 | (componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => {} | void | | +| getComponent | 获取 Component 的函数 | (Target: any, componentProps: {}, fieldProps: [MergedFieldComponentProps](#MergedFieldComponentProps)) => React.JSXElementConstructor | | **用法** ```typescript -import {registerFormField,connect} from '@formily/next' +import { registerFormField, connect } from '@formily/next' registerFormField( 'string', @@ -1529,7 +1590,6 @@ const Input = connect({ })(Input)) ``` - #### registerFormFields 全局批量注册拓展组件 @@ -1537,6 +1597,7 @@ const Input = connect({ ```typescript function registerFormFields(object: ISchemaFormRegistry['fields']) ``` + **用法** ```jsx @@ -1550,10 +1611,20 @@ import { } from '@formily/next' // 或者 @formily/next const CustomComponent1 = props => { - return props.onChange(e.target.value)} /> + return ( + props.onChange(e.target.value)} + /> + ) } const CustomComponent2 = props => { - return props.onChange(e.target.value)} + /> + ) } registerFormFields({ @@ -1564,8 +1635,16 @@ registerFormFields({ const App = () => { return ( - - + + ) } @@ -1575,7 +1654,7 @@ ReactDOM.render(, document.getElementById('root')) #### registerFormComponent -全局扩展 `
` UI组件 +全局扩展 `` UI 组件 ```typescript function registerFormComponent( @@ -1588,7 +1667,11 @@ function registerFormComponent( ```tsx import React from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, SchemaMarkupField as Field, registerFormComponent } from '@formily/next' +import { + SchemaForm, + SchemaMarkupField as Field, + registerFormComponent +} from '@formily/next' import { Input } from '@formily/next-components' registerFormComponent(props => { @@ -1611,9 +1694,7 @@ ReactDOM.render(, document.getElementById('root')) 全局扩展 `` UI 组件 ```typescript -function registerFormItemComponent( - component: React.JSXElementConstructor -) +function registerFormItemComponent(component: React.JSXElementConstructor) ``` **用法** @@ -1621,7 +1702,11 @@ function registerFormItemComponent( ```tsx import React from 'react' import ReactDOM from 'react-dom' -import { SchemaForm, SchemaMarkupField as Field, registerFormItemComponent } from '@formily/next' +import { + SchemaForm, + SchemaMarkupField as Field, + registerFormItemComponent +} from '@formily/next' import { Input } from '@formily/next-components' registerFormItemComponent(props => { @@ -1639,7 +1724,6 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - #### registerFormField ```typescript @@ -1653,8 +1737,12 @@ type registerFormField( **用法** ```tsx - -import SchemaForm, { SchemaMarkupField as Field, registerFormField, connect, createFormActions } from '@formily/next' +import SchemaForm, { + SchemaMarkupField as Field, + registerFormField, + connect, + createFormActions +} from '@formily/next' registerFormField( 'custom-string', @@ -1664,7 +1752,7 @@ const actions = createFormActions() const App = () => { return ( - + ) @@ -1687,23 +1775,28 @@ function createControllerBox( **用法** ```jsx - -import SchemaForm, { SchemaMarkupField as Field, createControllerBox, createFormActions } from '@formily/next' +import SchemaForm, { + SchemaMarkupField as Field, + createControllerBox, + createFormActions +} from '@formily/next' import { Input } from '@formily/next-components' -const FormLayout = createControllerBox('controller-form-layout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+const FormLayout = createControllerBox('controller-form-layout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) const App = () => { return ( - + - + ) } @@ -1725,23 +1818,28 @@ function createVirtualBox( **用法** ```jsx - -import SchemaForm, { SchemaMarkupField as Field, createVirtualBox, createFormActions } from '@formily/next' +import SchemaForm, { + SchemaMarkupField as Field, + createVirtualBox, + createFormActions +} from '@formily/next' import { Input } from '@formily/next-components' -const FormLayout = createVirtualBox('c-form-layout', (props) => { - return
- {props.children} - {props.attr} -
+const FormLayout = createVirtualBox('c-form-layout', props => { + return ( +
+ {props.children} + {props.attr} +
+ ) }) const App = () => { return ( - + - + ) } @@ -1749,7 +1847,6 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - #### registerVirtualBox 注册虚拟表单字段,常用于生成表单布局组件。这种方式主要适用于 `json-schema` 模式下。 @@ -1764,20 +1861,24 @@ function registerVirtualBox( **用法** ```jsx - -import SchemaForm, { SchemaMarkupField as Field, registerVirtualBox } from '@formily/next' +import SchemaForm, { + SchemaMarkupField as Field, + registerVirtualBox +} from '@formily/next' import { Input } from '@formily/next-components' -registerVirtualBox('CustomLayout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+registerVirtualBox('CustomLayout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) const App = () => { return ( - + { }} > - + ) } @@ -1817,14 +1918,18 @@ function getRegistry () => ISchemaFormRegistry **用法** ```tsx +import SchemaForm, { + SchemaMarkupField as Field, + getRegistry +} from '@formily/next' -import SchemaForm, { SchemaMarkupField as Field, getRegistry } from '@formily/next' - -registerVirtualBox('CustomLayout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+registerVirtualBox('CustomLayout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) getRegistry() @@ -1835,20 +1940,24 @@ getRegistry() 清理预先注册的所有组件。 ```typescript -function cleanRegistry () +function cleanRegistry() ``` **用法** ```tsx +import SchemaForm, { + SchemaMarkupField as Field, + cleanRegistry +} from '@formily/next' -import SchemaForm, { SchemaMarkupField as Field, cleanRegistry } from '@formily/next' - -registerVirtualBox('CustomLayout', (props) => { - return
- {props.children} - {props.schema['x-component-props']['attr']} -
+registerVirtualBox('CustomLayout', props => { + return ( +
+ {props.children} + {props.schema['x-component-props']['attr']} +
+ ) }) cleanRegistry() @@ -1923,7 +2032,6 @@ interface ISchema { } ``` - #### IFormActions ```typescript @@ -1969,7 +2077,7 @@ interface IFormActions { //重置范围,用于批量或者精确控制要重置的字段 selector?: FormPathPattern //是否清空默认值 - clearInitialValue?:boolean + clearInitialValue?: boolean }): Promise /* @@ -2099,7 +2207,7 @@ interface IFormAsyncActions { //重置范围,用于批量或者精确控制要重置的字段 selector?: FormPathPattern //是否清空默认值 - clearInitialValue?:boolean + clearInitialValue?: boolean }): Promise /* * 获取状态变化情况,主要用于在表单生命周期钩子内判断当前生命周期中有哪些状态发生了变化, @@ -2170,7 +2278,6 @@ interface IFormAsyncActions { } ``` - #### ButtonProps ```typescript @@ -2252,7 +2359,6 @@ interface ISchemaFieldAdaptorProps } ``` - #### IFieldState ```typescript @@ -2319,7 +2425,6 @@ interface IFieldState { } ``` - #### ISchemaFieldComponentProps ```typescript @@ -2394,7 +2499,6 @@ interface ISchemaFormRegistry { } ``` - #### InternalFormats ```typescript @@ -2553,23 +2657,25 @@ interface IPreviewTextProps { innerAfter?: React.ReactNode addonAfter?: React.ReactNode } - ``` #### IMutators ```typescript interface IMutators { - change: (value: V)=> void,//改变当前字段值 - dispatch: (name: string, payload : any) => void,//触发effect事件 - errors: (errors: string | Array, ...formatValues: Array) => void,//设置当前字段的错误消息 - push(value: V),//对当前字段的值做push操作 - pop(),//对当前字段的值做pop操作 - insert(index: number,value: V),//对当前字段的值做insert操作 - remove(name : string),//对当前字段的值做remove操作 - unshift(value : V),//对当前字段值做unshift操作 - shift(),//对当前字段值做shift操作 - move(fromIndex: number, toIndex: number)//对当前字段值做move操作 + change: (value: V) => void //改变当前字段值 + dispatch: (name: string, payload: any) => void //触发effect事件 + errors: ( + errors: string | Array, + ...formatValues: Array + ) => void //设置当前字段的错误消息 + push(value: V) //对当前字段的值做push操作 + pop() //对当前字段的值做pop操作 + insert(index: number, value: V) //对当前字段的值做insert操作 + remove(name: string) //对当前字段的值做remove操作 + unshift(value: V) //对当前字段值做unshift操作 + shift() //对当前字段值做shift操作 + move(fromIndex: number, toIndex: number) //对当前字段值做move操作 } ``` @@ -2577,26 +2683,32 @@ interface IMutators { ```typescript interface IFieldProps { - name : string //字段数据路径 - path : Array //字段数组数据路径 - value : V //字段值 - errors : Array //字段错误消息集合 - editable : boolean | ((name:string) => boolean) //字段是否可编辑 - locale : Locale //国际化文案对象 - loading : boolean //是否处于加载态 - schemaPath : Array //schema path,考虑到有些schema其实是不占数据路径的,所以这个路径是真实路径 - getSchema : (path: string) => ISchema //根据路径获取schema - renderField : (childKey: string, reactKey: string | number) => JSX.Element | string | null //根据childKey渲染当前字段的子字段 - renderComponent : React.FunctionComponent | undefined>,//渲染当前字段的组件,对于x-render来说,可以借助它快速实现渲染包装功能 - getOrderProperties : () => Array<{schema: ISchema, key: number, path: string, name: string }>,//根据properties里字段的x-index值求出排序后的properties - mutators : Mutators,//数据操作对象 - schema : ISchema + name: string //字段数据路径 + path: Array //字段数组数据路径 + value: V //字段值 + errors: Array //字段错误消息集合 + editable: boolean | ((name: string) => boolean) //字段是否可编辑 + locale: Locale //国际化文案对象 + loading: boolean //是否处于加载态 + schemaPath: Array //schema path,考虑到有些schema其实是不占数据路径的,所以这个路径是真实路径 + getSchema: (path: string) => ISchema //根据路径获取schema + renderField: ( + childKey: string, + reactKey: string | number + ) => JSX.Element | string | null //根据childKey渲染当前字段的子字段 + renderComponent: React.FunctionComponent | undefined> //渲染当前字段的组件,对于x-render来说,可以借助它快速实现渲染包装功能 + getOrderProperties: () => Array<{ + schema: ISchema + key: number + path: string + name: string + }> //根据properties里字段的x-index值求出排序后的properties + mutators: Mutators //数据操作对象 + schema: ISchema } - ``` ```typescript - interface IConnectOptions { //控制表单组件 valueName?: string @@ -2605,20 +2717,25 @@ interface IConnectOptions { //默认props defaultProps?: Partial //取值函数,有些场景我们的事件函数取值并不是事件回调的第一个参数,需要做进一步的定制 - getValueFromEvent?: (props: IFieldProps['x-props'], event: Event, ...args: any[]) => any + getValueFromEvent?: ( + props: IFieldProps['x-props'], + event: Event, + ...args: any[] + ) => any //字段组件props transformer - getProps?: (connectProps: IConnectProps, fieldProps: IFieldProps) => IConnectProps + getProps?: ( + connectProps: IConnectProps, + fieldProps: IFieldProps + ) => IConnectProps //字段组件component transformer - getComponent?: ( - target: T, + getComponent?: ( + target: T, connectProps: IConnectProps, fieldProps: IFieldProps ) => T } - ``` - ### IForm ```typescript @@ -2692,42 +2809,49 @@ interface IFormActions { setFieldInitialValue(path?: FormPathPattern, value?: any): void getFieldInitialValue(path?: FormPathPattern): any } - ``` #### IFormValidateResult ```typescript interface IFormValidateResult { - errors: Array<{ - path: string; - messages: string[]; - }>; - warnings: Array<{ - path: string; - messages: string[]; - }>; + errors: Array<{ + path: string + messages: string[] + }> + warnings: Array<{ + path: string + messages: string[] + }> } ``` #### IFormProps ```typescript -interface IFormProps { - value?: Value; - defaultValue?: DefaultValue; - initialValues?: DefaultValue; - actions?: FormActions; - effects?: IFormEffect; - form?: IForm; - onChange?: (values: Value) => void; - onSubmit?: (values: Value) => void | Promise; - onReset?: () => void; - onValidateFailed?: (valideted: IFormValidateResult) => void; - children?: React.ReactElement | React.ReactElement[] | ((form: IForm) => React.ReactElement); - useDirty?: boolean; - editable?: boolean | ((name: string) => boolean); - validateFirst?: boolean; +interface IFormProps< + Value = {}, + DefaultValue = {}, + FormEffectPayload = any, + FormActions = any +> { + value?: Value + defaultValue?: DefaultValue + initialValues?: DefaultValue + actions?: FormActions + effects?: IFormEffect + form?: IForm + onChange?: (values: Value) => void + onSubmit?: (values: Value) => void | Promise + onReset?: () => void + onValidateFailed?: (valideted: IFormValidateResult) => void + children?: + | React.ReactElement + | React.ReactElement[] + | ((form: IForm) => React.ReactElement) + useDirty?: boolean + editable?: boolean | ((name: string) => boolean) + validateFirst?: boolean } ``` @@ -2784,7 +2908,6 @@ interface MergedFieldComponentProps extends IFieldState { reactKey?: string | number ) => React.ReactElement } - ``` #### Pagination @@ -2828,4 +2951,4 @@ type IQueryResponse = { pageSize: number current: number } -``` \ No newline at end of file +``` diff --git a/packages/printer/README.md b/packages/printer/README.md index 4465b836339..eff16d3d8c7 100644 --- a/packages/printer/README.md +++ b/packages/printer/README.md @@ -1,2 +1,3 @@ # @formily/printer -> Formily Printer \ No newline at end of file + +> Formily Printer diff --git a/packages/react-schema-editor/README.md b/packages/react-schema-editor/README.md index 4e6483e4ece..7e687dd579f 100644 --- a/packages/react-schema-editor/README.md +++ b/packages/react-schema-editor/README.md @@ -1,7 +1,9 @@ # react-schema-editor + react-schema-editor is a UI tool for build form schema. ## Usage + ``` npm install @formily/react-schema-editor -S ``` @@ -14,169 +16,175 @@ import { SchemaEditor } from './src' function SchemaEditorDemo() { const [schema, setSchema] = React.useState({ - "type": "object", - "properties": { - "string": { - "type": "string", - "x-component": "Input", - "title": "String" - }, - "radio": { - "type": "string", - "x-component": "Radio", - "x-component-props": { - "options":[ - "1", - "2", - "3", - "4" - ] - }, - "title": "Radio" - }, - "select": { - "type": "string", - "x-component": "Select", - "x-component-props": { - "options": [{ - label: 'Jack', - key: 'jack', - value: 'jack', - },{ - label: 'Rose', - key: 'rose', - value: 'rose', - },{ - label: 'Others', - key: 'others', - value: 'others', - }] - }, - "title": "Select" - }, - "checkbox": { - "type": "string", - "x-component": "Checkbox", - "x-component-props" : { - options :['Apple', 'Pear', 'Orange'] - }, - "title": "Checkbox" - }, - "textarea": { - "type": "string", - "x-component": "Textarea", - "title": "TextArea" - }, - "number": { - "type": "number", - "x-component": "InputNumber", - "title": "数字选择" - }, - "boolean": { - "type": "boolean", - "x-component": "Switch", - "title": "开关选择" - }, - "date": { - "type": "string", - "x-component": "DatePicker", - "title": "日期选择" - }, - "daterange": { - "type": "object", - "x-component": "DateRangePicker", - "title": "日期范围" - }, - "year": { - "type": "string", - "x-component": "YearPicker", - "title": "年份" - }, - "month": { - "type": "string", - "x-component": "MonthPicker", - "title": "月份" - }, - "time": { - "type": "string", - "x-component": "TimePicker", - "title": "时间" - }, - "week": { - "type": "string", - "x-component": "WeekPicker", - "title": "周" - }, - "upload": { - "type": "array", - "x-component": "Upload", - "x-component-props": { - fileList:[ - { - uid: '-1', - name: 'image.png', - status: 'done', - url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', - }, - { - uid: '-2', - name: 'image.png', - status: 'done', - url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', - }, - { - uid: '-3', - name: 'image.png', - status: 'done', - url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', - }, - { - uid: '-4', - name: 'image.png', - status: 'done', - url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png', - }, - { - uid: '-5', - name: 'image.png', - status: 'error', - }, - ], - action:"https://www.mocky.io/v2/5cc8019d300000980a055e76", - listType:"picture-card" - }, - "title": "卡片上传文件" - }, - "range": { - "type": "number", - "x-component": "Range", - "title": "范围选择" - }, - "transfer": { - "type": "number", - "x-component": "Transfer", - "x-component-props": { - "dataSource":[{ - "key": "1", - "title": "选项1" - },{ - "key": "2", - "title": "选项2" - }] - }, - "title": "穿梭框" - }, - "rating": { - "type": "number", - "x-component": "Rate", - "title": "等级" + type: 'object', + properties: { + string: { + type: 'string', + 'x-component': 'Input', + title: 'String' + }, + radio: { + type: 'string', + 'x-component': 'Radio', + 'x-component-props': { + options: ['1', '2', '3', '4'] + }, + title: 'Radio' + }, + select: { + type: 'string', + 'x-component': 'Select', + 'x-component-props': { + options: [ + { + label: 'Jack', + key: 'jack', + value: 'jack' + }, + { + label: 'Rose', + key: 'rose', + value: 'rose' + }, + { + label: 'Others', + key: 'others', + value: 'others' + } + ] + }, + title: 'Select' + }, + checkbox: { + type: 'string', + 'x-component': 'Checkbox', + 'x-component-props': { + options: ['Apple', 'Pear', 'Orange'] + }, + title: 'Checkbox' + }, + textarea: { + type: 'string', + 'x-component': 'Textarea', + title: 'TextArea' + }, + number: { + type: 'number', + 'x-component': 'InputNumber', + title: '数字选择' + }, + boolean: { + type: 'boolean', + 'x-component': 'Switch', + title: '开关选择' + }, + date: { + type: 'string', + 'x-component': 'DatePicker', + title: '日期选择' + }, + daterange: { + type: 'object', + 'x-component': 'DateRangePicker', + title: '日期范围' + }, + year: { + type: 'string', + 'x-component': 'YearPicker', + title: '年份' + }, + month: { + type: 'string', + 'x-component': 'MonthPicker', + title: '月份' + }, + time: { + type: 'string', + 'x-component': 'TimePicker', + title: '时间' + }, + week: { + type: 'string', + 'x-component': 'WeekPicker', + title: '周' + }, + upload: { + type: 'array', + 'x-component': 'Upload', + 'x-component-props': { + fileList: [ + { + uid: '-1', + name: 'image.png', + status: 'done', + url: + 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' + }, + { + uid: '-2', + name: 'image.png', + status: 'done', + url: + 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' + }, + { + uid: '-3', + name: 'image.png', + status: 'done', + url: + 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' + }, + { + uid: '-4', + name: 'image.png', + status: 'done', + url: + 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png' + }, + { + uid: '-5', + name: 'image.png', + status: 'error' + } + ], + action: 'https://www.mocky.io/v2/5cc8019d300000980a055e76', + listType: 'picture-card' + }, + title: '卡片上传文件' + }, + range: { + type: 'number', + 'x-component': 'Range', + title: '范围选择' + }, + transfer: { + type: 'number', + 'x-component': 'Transfer', + 'x-component-props': { + dataSource: [ + { + key: '1', + title: '选项1' + }, + { + key: '2', + title: '选项2' + } + ] + }, + title: '穿梭框' + }, + rating: { + type: 'number', + 'x-component': 'Rate', + title: '等级' + } } - } -}) + }) // return
Hello
return } ReactDOM.render(, document.getElementById('root')) -```` +``` diff --git a/packages/react-schema-renderer/README.md b/packages/react-schema-renderer/README.md index 0b5b87fbac9..57ec0d205fc 100644 --- a/packages/react-schema-renderer/README.md +++ b/packages/react-schema-renderer/README.md @@ -276,11 +276,11 @@ import { } from '@formily/react-schema-renderer' import { Form } from 'antd' -export const CompatFormComponent = ({children,...props})=>{ +export const CompatFormComponent = ({ children, ...props }) => { return {children} //Very simple to use the Form component, props is the props of the SchemaForm component, here will be directly transparent } -export const CompatFormItemComponent = ({children,...props})=>{ +export const CompatFormItemComponent = ({ children, ...props }) => { const messages = [].concat(props.errors || [], props.warnings || []) let status = '' if (props.loading) { @@ -296,9 +296,11 @@ export const CompatFormItemComponent = ({children,...props})=>{ + > {children} ) @@ -311,15 +313,14 @@ registerFormItemComponent(CompatFormItemComponent) ***/ //Single case registration method -export default ()=>{ +export default () => { return ( ) } - ``` We can see that extending the overall or partial style of the form can be easily solved by simply extending the Form/FormItem component. It should be noted here that the props received by the FormItem component are a bit complicated. Don't worry, the detailed props API will be listed later. Now we just need to know how it is probably registered. @@ -900,7 +901,7 @@ cleanRegistry(): void | Attribute name | Description | Type | | -------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | title | Field title | `React.ReactNode` | -| name | The parent property name of the field | `string` | +| name | The parent property name of the field | `string` | | description | Field description | `React.ReactNode` | | default | Field default | `any` | | readOnly | Whether read-only and editable | `boolean` | @@ -927,9 +928,9 @@ cleanRegistry(): void | additionalItems | Extra array element description | `Schema` | | patternProperties | Dynamically match the schema of an attribute of an object | `{[key : string]:Schema}` | | additionalProperties | Schema matching the extra attributes of the object | `Schema` | -| editable | Whether the field is editable | `boolean` | -| visible | Whether the data and style is visible | `boolean` | -| display | Whether the style is visible | `boolean` | +| editable | Whether the field is editable | `boolean` | +| visible | Whether the data and style is visible | `boolean` | +| display | Whether the style is visible | `boolean` | | x-props | Field extension attribute | `{ [name: string]: any }` | | x-index | Field order | `number` | | x-rules | Field check rule | `ValidatePatternRules` | @@ -1578,20 +1579,20 @@ interface IConnectOptions { eventName?: string //get value callback name defaultProps?: {} //component default props getValueFromEvent?: (event?: any, value?: any) => any //get value from event callback. - getProps?: ( //props transformer + getProps?: ( + //props transformer componentProps: {}, fieldProps: MergedFieldComponentProps ) => {} | void - getComponent?: ( //component transformer + getComponent?: ( + //component transformer Target: any, componentProps: {}, fieldProps: MergedFieldComponentProps ) => React.JSXElementConstructor } - ``` - #### ISchemaFieldComponentProps > It is very important to customize the properties received by the component. As long as it involves developing custom components, you need to understand the protocol. diff --git a/packages/react-schema-renderer/README.zh-cn.md b/packages/react-schema-renderer/README.zh-cn.md index b3266681eed..6bdebbcb0ad 100644 --- a/packages/react-schema-renderer/README.zh-cn.md +++ b/packages/react-schema-renderer/README.zh-cn.md @@ -272,11 +272,11 @@ import { } from '@formily/react-schema-renderer' import { Form } from 'antd' -export const CompatFormComponent = ({children,...props})=>{ +export const CompatFormComponent = ({ children, ...props }) => { return
{children}
//很简单的使用Form组件,props是SchemaForm组件的props,这里会直接透传 } -export const CompatFormItemComponent = ({children,...props})=>{ +export const CompatFormItemComponent = ({ children, ...props }) => { const messages = [].concat(props.errors || [], props.warnings || []) let status = '' if (props.loading) { @@ -292,9 +292,11 @@ export const CompatFormItemComponent = ({children,...props})=>{ + > {children} ) @@ -307,15 +309,14 @@ registerFormItemComponent(CompatFormItemComponent) ***/ //单例注册方式 -export default ()=>{ +export default () => { return ( ) } - ``` 我们可以看到,扩展表单整体或局部的样式,仅仅只需要通过扩展 Form/FormItem 组件就可以轻松解决了,这里需要注意的是,FormItem 组件接收到的 props 有点复杂,不用担心,后面会列出详细 props API,现在我们只需要知道大概是如何注册的就行了。 @@ -900,7 +901,7 @@ cleanRegistry(): void | 属性名 | 描述 | 类型 | | -------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | title | 字段标题 | `React.ReactNode` | -| name | 字段所属的父节点属性名 | `string` | +| name | 字段所属的父节点属性名 | `string` | | description | 字段描述 | `React.ReactNode` | | default | 字段默认值 | `any` | | readOnly | 是否只读与 editable 一致 | `boolean` | @@ -927,10 +928,10 @@ cleanRegistry(): void | additionalItems | 额外数组元素描述 | `Schema` | | patternProperties | 动态匹配对象的某个属性的 Schema | `{[key : string]:Schema}` | | additionalProperties | 匹配对象额外属性的 Schema | `Schema` | -| editable | 字段是否可编辑 | `boolean` | -| visible | 字段是否可见(数据+样式) | `boolean` | -| display | 字段样式是否可见 | `boolean` | -| x-props | 字段扩展属性 | `{ [name: string]: any }` | +| editable | 字段是否可编辑 | `boolean` | +| visible | 字段是否可见(数据+样式) | `boolean` | +| display | 字段样式是否可见 | `boolean` | +| x-props | 字段扩展属性 | `{ [name: string]: any }` | | x-index | 字段顺序 | `number` | | x-rules | 字段校验规则 | `ValidatePatternRules` | | x-component | 字段 UI 组件 | `string` | @@ -1192,8 +1193,6 @@ const schema4 = new Schema({ schema4.getExtendsEditable() // false ``` - - ##### `getExtendsVisible` > 获取数据样式可见属性 @@ -1214,8 +1213,6 @@ getExtendsVisible(): boolean getExtendsDisplay() : boolean ``` - - ##### `getExtendsTriggerType` > 获取 triggerType,与 getExtendsEditable 能力一致,都是提供协议差异抹平的能力 @@ -1582,17 +1579,18 @@ interface IConnectOptions { eventName?: string //取值回调名称,默认是onChange defaultProps?: {} //自定义组件默认属性 getValueFromEvent?: (event?: any, value?: any) => any //取值回调处理器,主要用于针对事件参数到最终触发onChange的值做转换合并 - getProps?: ( //组件属性转换器,使用它可以轻松的处理从FieldProps到ComponentProps的转换映射等工作 + getProps?: ( + //组件属性转换器,使用它可以轻松的处理从FieldProps到ComponentProps的转换映射等工作 componentProps: {}, fieldProps: MergedFieldComponentProps ) => {} | void - getComponent?: ( //组件转换器,有些场景,根据FieldState,会将组件做动态切换,比如根据editable,会动态切换为文本预览组件之类的 + getComponent?: ( + //组件转换器,有些场景,根据FieldState,会将组件做动态切换,比如根据editable,会动态切换为文本预览组件之类的 Target: any, componentProps: {}, fieldProps: MergedFieldComponentProps ) => React.JSXElementConstructor } - ``` #### ISchemaFieldComponentProps diff --git a/packages/react-shared-components/README.md b/packages/react-shared-components/README.md index 1e9024d4ef7..da369aa55b2 100644 --- a/packages/react-shared-components/README.md +++ b/packages/react-shared-components/README.md @@ -1,2 +1,3 @@ # @formily/react-shared -> Formily React通用库 \ No newline at end of file + +> Formily React 通用库 diff --git a/packages/react/README.md b/packages/react/README.md index 6b7d667aa07..118195c56fc 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -210,9 +210,7 @@ const App = () => { name="age" rules={[ val => - !val - ? { type: 'error', message: 'age is required' } - : undefined + !val ? { type: 'error', message: 'age is required' } : undefined ]} /> @@ -547,7 +545,6 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - #### display visible Example: see how `display` 与 `visible` affect values @@ -555,24 +552,36 @@ Example: see how `display` 与 `visible` affect values ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, LifeCycleTypes, FormSpy } from '@formily/react' +import { + Form, + Field, + createFormActions, + LifeCycleTypes, + FormSpy +} from '@formily/react' const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -581,14 +590,24 @@ const CheckedField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : { - mutators.change(!state.value) - }} checked={!!state.value} /> } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + { + mutators.change(!state.value) + }} + checked={!!state.value} + /> + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -600,48 +619,51 @@ const App = () => { actions={actions} effects={($, { validate, setFieldState }) => { $(LifeCycleTypes.ON_FORM_INIT).subscribe(() => { - setFieldState('displayTrigger', state => state.value = true) - setFieldState('visibleTrigger', state => state.value = true) - setFieldState('a', state => state.value = 1) - setFieldState('b', state => state.value = 2) + setFieldState('displayTrigger', state => (state.value = true)) + setFieldState('visibleTrigger', state => (state.value = true)) + setFieldState('a', state => (state.value = 1)) + setFieldState('b', state => (state.value = 2)) }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'visibleTrigger').subscribe((fieldState) => { - setFieldState('a', state => { - state.visible = fieldState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'visibleTrigger').subscribe( + fieldState => { + setFieldState('a', state => { + state.visible = fieldState.value + }) + } + ) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'displayTrigger').subscribe((fieldState) => { - setFieldState('b', state => { - state.display = fieldState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'displayTrigger').subscribe( + fieldState => { + setFieldState('b', state => { + state.display = fieldState.value + }) + } + ) }} >
- + - +
- - + +
{({ state, form }) => { - return (
- {JSON.stringify(form.getFormState(state => state.values))} -
) + return ( +
+ {JSON.stringify(form.getFormState(state => state.values))} +
+ ) }}
- @@ -652,7 +674,6 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - #### Linkage Example:Show/hide field and modified props/value by using effects @@ -666,18 +687,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -686,14 +713,24 @@ const CheckedField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : { - mutators.change(!state.value) - }} checked={!!state.value} /> } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + { + mutators.change(!state.value) + }} + checked={!!state.value} + /> + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -705,16 +742,18 @@ const App = () => { actions={actions} effects={($, { setFieldState }) => { $(LifeCycleTypes.ON_FORM_INIT).subscribe(() => { - setFieldState('a~', state => state.visible = false) + setFieldState('a~', state => (state.visible = false)) }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((triggerState) => { - setFieldState('a~', state => { - state.visible = triggerState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe( + triggerState => { + setFieldState('a~', state => { + state.visible = triggerState.value + }) + } + ) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe((fieldState) => { + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe(fieldState => { setFieldState('a-copy', state => { state.value = fieldState.value }) @@ -748,18 +787,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -767,14 +812,24 @@ const CheckedField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : { - mutators.change(!state.value) - }} checked={!!state.value} /> } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + { + mutators.change(!state.value) + }} + checked={!!state.value} + /> + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -783,20 +838,28 @@ const SelectField = props => ( {({ state, mutators }) => { const { loading, dataSource = [] } = state.props - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -807,8 +870,12 @@ const App = () => {
{ - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((fieldState) => { - const dataSource = [{ label: 'aa', value: 'aa' }, { label: 'bb', value: 'bb' } ] + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe( + fieldState => { + const dataSource = [ + { label: 'aa', value: 'aa' }, + { label: 'bb', value: 'bb' } + ] setFieldState('sync-source', state => { state.props.dataSource = fieldState.value ? dataSource : [] }) @@ -822,7 +889,8 @@ const App = () => { state.props.dataSource = fieldState.value ? dataSource : [] }) }, 300) - }) + } + ) }} > @@ -852,18 +920,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -878,7 +952,7 @@ const App = () => { validate() }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe((fieldState) => { + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe(fieldState => { setFieldState('a-copy', state => { state.value = fieldState.value }) @@ -887,7 +961,7 @@ const App = () => { >
- +
) @@ -909,18 +983,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -937,87 +1017,98 @@ const App = () => { }) }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((fieldState) => { - setFieldState('userList.*.username', state => { - state.visible = fieldState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe( + fieldState => { + setFieldState('userList.*.username', state => { + state.visible = fieldState.value + }) + } + ) }} >
- - {({ state, mutators }) => { - return - }} - + + {({ state, mutators }) => { + return ( + + ) + }} +
- + {({ state, mutators }) => { - return ( - - {state.value.map((item, index) => { - return ( -
- - {({ state: innerState, mutators: innerMutator }) => { - return ( - - {Object.keys(innerState.value).map(key => { - if (!innerMutator.exist(key)) return - return ( - - - - ) - })} - - - ) - }} - + return ( + + {state.value.map((item, index) => { + return ( +
+ + {({ state: innerState, mutators: innerMutator }) => { + return ( + + {Object.keys(innerState.value).map(key => { + if (!innerMutator.exist(key)) return + return ( + + + + ) + })} + + + ) + }} + - -
- ) - })} - - -
- ) - }} + +
+ ) + })} + + +
+ ) + }}
@@ -1036,23 +1127,28 @@ import React from 'react' import ReactDOM from 'react-dom' import { Form, Field, createFormActions, FormEffectHooks } from '@formily/react' - const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1060,36 +1156,46 @@ const CheckedField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : { - mutators.change(!state.value) - }} checked={!!state.value} /> } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + { + mutators.change(!state.value) + }} + checked={!!state.value} + /> + )} + {state.errors} + {state.warnings} + + ) }} ) -const { onFormMount$, onFieldValueChange$ } = FormEffectHooks -const getEffects = ()=>{ - const actions = createFormActions() - onFormMount$().subscribe(() => { - actions.setFieldState('a~', state => state.visible = false) - }) +const { onFormMount$, onFieldValueChange$ } = FormEffectHooks +const getEffects = () => { + const actions = createFormActions() + onFormMount$().subscribe(() => { + actions.setFieldState('a~', state => (state.visible = false)) + }) - onFieldValueChange$('trigger').subscribe((triggerState) => { - actions.setFieldState('a~', state => { - state.visible = triggerState.value - }) + onFieldValueChange$('trigger').subscribe(triggerState => { + actions.setFieldState('a~', state => { + state.visible = triggerState.value }) + }) - onFieldValueChange$('a').subscribe((fieldState) => { - actions.setFieldState('a-copy', state => { - state.value = fieldState.value - }) + onFieldValueChange$('a').subscribe(fieldState => { + actions.setFieldState('a-copy', state => { + state.value = fieldState.value }) + }) } const actions = createFormActions() @@ -1182,7 +1288,13 @@ Example:Cross-file consumption form state, Check [FormProvider](#FormProvider) ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, FormSpy, FormProvider } from '@formily/react' +import { + Form, + Field, + createFormActions, + FormSpy, + FormProvider +} from '@formily/react' const actions = createFormActions() const InputField = props => ( @@ -1241,45 +1353,68 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React, { useState } from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, FormSpy, FormPath } from '@formily/react' +import { + Form, + Field, + createFormActions, + FormSpy, + FormPath +} from '@formily/react' const actions = createFormActions() const App = () => { return ( -
+ {({ state, mutators }) => { - const [start, end] = state.value - return
- - { - mutators.change([e.target.value, end]) - }} /> - - { - mutators.change([start, e.target.value]) - }} /> -
+ return ( +
+ + { + mutators.change([e.target.value, end]) + }} + /> + + { + mutators.change([start, e.target.value]) + }} + /> +
+ ) }}
- + {({ state, form }) => { - return (
- Form values: - -
-                {JSON.stringify(form.getFormState(state => state.values), null, 2)}
-              
-
-
) + return ( +
+ Form values: + +
+                  {JSON.stringify(
+                    form.getFormState(state => state.values),
+                    null,
+                    2
+                  )}
+                
+
+
+ ) }}
@@ -1294,83 +1429,109 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React, { useState } from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, FormSpy, FormPath } from '@formily/react' +import { + Form, + Field, + createFormActions, + FormSpy, + FormPath +} from '@formily/react' const actions = createFormActions() const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) - const App = () => { return ( -
+ {({ state, mutators }) => { - return
- -
Field value:
- -
{JSON.stringify(state.value, null, 2)}
-
-
+ }) + }} + > + set value + +
Field value:
+ +
{JSON.stringify(state.value, null, 2)}
+
+
+ ) }} - {({ state, form }) => { - return (
- Form values: - -
-                {JSON.stringify(form.getFormState(state => state.values), null, 2)}
-              
-
-
) + return ( +
+ Form values: + +
+                  {JSON.stringify(
+                    form.getFormState(state => state.values),
+                    null,
+                    2
+                  )}
+                
+
+
+ ) }}
@@ -1625,13 +1786,9 @@ const App = () => { ) }} - -
@@ -1765,7 +1922,13 @@ Example1: Form state change counter ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, FormSpy, LifeCycleTypes } from '@formily/react' +import { + Form, + Field, + createFormActions, + FormSpy, + LifeCycleTypes +} from '@formily/react' const actions = createFormActions() const InputField = props => ( @@ -1808,7 +1971,6 @@ const App = () => { } ReactDOM.render(, document.getElementById('root')) - ``` Example2:Combo @@ -1868,11 +2030,16 @@ ReactDOM.render(, document.getElementById('root')) **Usage** - ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, FormSpy, FormProvider } from '@formily/react' +import { + Form, + Field, + createFormActions, + FormSpy, + FormProvider +} from '@formily/react' const actions = createFormActions() const InputField = props => ( @@ -1940,13 +2107,12 @@ interface IFormConsumerProps { } ``` - ### Hook #### `useFormEffects` > Implement local effects by using useFormEffects. Same effect as the example of [Linkage](#Linkage) -> Note: The life cycle of the listener starts from `ON_FORM_MOUNT` +> Note: The life cycle of the listener starts from `ON_FORM_MOUNT` **Signature** @@ -1957,25 +2123,37 @@ interface IFormConsumerProps { ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, useFormEffects, LifeCycleTypes } from '@formily/react' +import { + Form, + Field, + createFormActions, + useFormEffects, + LifeCycleTypes +} from '@formily/react' const actions = createFormActions() const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1984,14 +2162,24 @@ const CheckedField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : { - mutators.change(!state.value) - }} checked={!!state.value} /> } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + { + mutators.change(!state.value) + }} + checked={!!state.value} + /> + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1999,16 +2187,18 @@ const CheckedField = props => ( const FormFragment = () => { useFormEffects(($, { setFieldState }) => { $(LifeCycleTypes.ON_FORM_INIT).subscribe(() => { - setFieldState('a~', state => state.visible = false) + setFieldState('a~', state => (state.visible = false)) }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((triggerState) => { - setFieldState('a~', state => { - state.visible = triggerState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe( + triggerState => { + setFieldState('a~', state => { + state.visible = triggerState.value + }) + } + ) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe((fieldState) => { + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe(fieldState => { setFieldState('a-copy', state => { state.value = fieldState.value }) @@ -2030,9 +2220,7 @@ const FormFragment = () => { const App = () => { return ( -
+ ) @@ -2043,7 +2231,7 @@ ReactDOM.render(, document.getElementById('root')) #### `useFormState` -> 使用 useFormState 为自定义组件提供FormState扩展和管理能力 +> 使用 useFormState 为自定义组件提供 FormState 扩展和管理能力 **签名** @@ -2056,8 +2244,12 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { Form, Field, VirtualField, - createFormActions, createEffectHook, +import { + Form, + Field, + VirtualField, + createFormActions, + createEffectHook, useForm, useFormState, useFormEffects, @@ -2069,33 +2261,45 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) const actions = createFormActions() -const FormFragment = (props) => { - const [formState, setFormState ] = useFormState({ extendVar: 0 }) +const FormFragment = props => { + const [formState, setFormState] = useFormState({ extendVar: 0 }) const { extendVar } = formState - return
- -
count: {extendVar}
-
+ return ( +
+ +
count: {extendVar}
+
+ ) } const App = () => { @@ -2122,8 +2326,12 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { Form, Field, VirtualField, - createFormActions, createEffectHook, +import { + Form, + Field, + VirtualField, + createFormActions, + createEffectHook, useForm, useFormEffects, useFieldState, @@ -2134,31 +2342,37 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) const changeTab$ = createEffectHook('changeTab') const actions = createFormActions() -const TabFragment = (props) => { - const [fieldState, setLocalFieldState ] = useFieldState({ current: 0 }) +const TabFragment = props => { + const [fieldState, setLocalFieldState] = useFieldState({ current: 0 }) const { current } = fieldState const { children, dataSource, form } = props const ref = useRef(current) - const update = (cur) => { + const update = cur => { form.notify('changeTab', cur) setLocalFieldState({ current: cur @@ -2172,45 +2386,57 @@ const TabFragment = (props) => { }) }) - changeTab$().subscribe((idx) => { + changeTab$().subscribe(idx => { dataSource.forEach((item, itemIdx) => { - setFieldState(item.name, state => { - state.display = itemIdx === idx + setFieldState(item.name, state => { + state.display = itemIdx === idx + }) }) }) - }) }) ref.current = current const btns = dataSource.map((item, idx) => { console.log('current', current, ref.current) - const focusStyle = idx === current ? { color: '#fff', background: 'blue' } : {} - return + const focusStyle = + idx === current ? { color: '#fff', background: 'blue' } : {} + return ( + + ) }) return btns } -const FormTab = (props) => { - return - {({ form }) => { - return - }} - +const FormTab = props => { + return ( + + {({ form }) => { + return + }} + + ) } const App = () => { return (
- +
- - + +
) @@ -2262,15 +2488,19 @@ type useField = (options: IFieldStateUIProps): IFieldHook ```typescript import { useField } from '@formily/react' -const FormFragment = (props) => { - const { - form, - state, - props: fieldProps, - mutators - } = useField({ name: 'username' }) +const FormFragment = props => { + const { form, state, props: fieldProps, mutators } = useField({ + name: 'username' + }) - return + return ( + + ) } ``` @@ -2289,16 +2519,16 @@ type UseVirtualField = (options: IVirtualFieldStateProps): IVirtualFieldHook ```typescript import { UseVirtualField } from '@formily/react' -const FormFragment = (props) => { - const { - form, - state, - props: fieldProps, - } = UseVirtualField({ name: 'username' }) +const FormFragment = props => { + const { form, state, props: fieldProps } = UseVirtualField({ + name: 'username' + }) - return
- {props.children} -
+ return ( +
+ {props.children} +
+ ) } ``` @@ -2316,21 +2546,19 @@ type useFormSpy = (props: IFormSpyProps): ISpyHook ```typescript import { useFormSpy, LifeCycleTypes } from '@formily/react' -const FormFragment = (props) => { - const { - form, - state, - type, - } = useFormSpy({ +const FormFragment = props => { + const { form, state, type } = useFormSpy({ selector: LifeCycleTypes.ON_FORM_VALUES_CHANGE, reducer: (state, action, form) => ({ count: state.count ? state.count + 1 : 1 }) }) - return
-
count: {state.count || 0}
-
+ return ( +
+
count: {state.count || 0}
+
+ ) } ``` @@ -2489,21 +2717,29 @@ const App = () => {
{ - diyHook1$().subscribe((payload) => { + diyHook1$().subscribe(payload => { console.log('diy1 hook triggered', payload) }) - diyHook2$().subscribe((payload) => { + diyHook2$().subscribe(payload => { console.log('diy2 hook triggered', payload) }) }} > - - + +
) } @@ -2511,220 +2747,168 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - ### Interfaces > The Interfaces is fully inherited from @formily/core. The specific Interfaces of @formily/react is listed below. --- -#### IForm - - +#### IForm > Form instance object API created by using createForm - - ```typescript interface IForm { -  /* -   * Form submission, if the callback parameter returns Promise, -   * Then the entire submission process will hold and load is true. -   * Wait for Promise resolve to trigger the form onFormSubmitEnd event while loading is false -   */ -   submit( -      onSubmit?: (values: IFormState['values']) => any | Promise -    ): Promise<{ -       Validated: IFormValidateResult -       Payload: any //onSubmit callback function return value -   }> -    -   /* -    * Clear the error message, you can pass the FormPathPattern to batch or precise control of the field to be cleared. -    * For example, clearErrors("*(aa,bb,cc)") -    */ -   clearErrors: (pattern?: FormPathPattern) => void -    -   /* -    * Get status changes, mainly used to determine which states in the current life cycle have changed in the form lifecycle hook. -    * For example, hasChanged(state,'value.aa') -    */ -   hasChanged(target: IFormState | IFieldState | IVirtualFieldState, path: FormPathPattern): boolean -    -   /* -    * Reset form -    */ -   reset(options?: { -     // Forced to empty -     forceClear?: boolean -     // Forced check -     validate?: boolean -     // Reset range for batch or precise control of the field to be reset -     selector?: FormPathPattern - //clear initialValue - clearInitialValue?:boolean -   }): Promise -    -   /* -    * Validation form -    */ -   validate(path?: FormPathPattern, options?: { -     // Is it pessimistic check, if the current field encounters the first verification error, stop the subsequent verification process -     first?:boolean -   }): Promise -    -   /* -    * Set the form status -    */ -   setFormState( -     // Operation callback -     callback?: (state: IFormState) => any, -     // No trigger the event -     silent?: boolean -   ): void -    -   /* -    * Get form status -    */ -   getFormState( -     //transformer -     callback?: (state: IFormState) => any -   ): any -    -   /* -    * Set the field status -    */ -   setFieldState( -     // Field path -     path: FormPathPattern, -     // Operation callback -     callback?: (state: IFieldState) => void, -     // No trigger the event -     silent?: boolean -   ): void -    -   /* -    * Get the field status -    */ -   getFieldState( -     // Field path -     path: FormPathPattern, -     // Transformer -     callback?: (state: IFieldState) => any -   ): any -    -   /* -    * Registration field -    */ -   registerField(props: { -    // Node path -    path?: FormPathPattern -    // Data path -    name?: string -    // Field value -    value?: any -    // Field multi-value -    values?: any[] -    // Field initial value -    initialValue?: any -    // Field extension properties -    props?: any -    // Field check rule -    rules?: ValidatePatternRules[] -    // Field is required -    required?: boolean -    // Is the field editable? -    editable?: boolean -    // Whether the field is dirty check -    useDirty?: boolean -    // Field state calculation container, mainly used to extend the core linkage rules -    computeState?: (draft: IFieldState, prevState: IFieldState) => void -  }): IField -   -  /* -   * Register virtual fields -   */ -  registerVirtualField(props: { -    // Node path -    path?: FormPathPattern -    // Data path -    name?: string -    // Field extension properties -    props?: any -    // Whether the field is dirty check -    useDirty?: boolean -    // Field state calculation container, mainly used to extend the core linkage rules -    computeState?: (draft: IFieldState, prevState: IFieldState) => void -  }): IVirtualField -   -  /* -   * Create a field data operator, which will explain the returned API in detail later. -   */ -  createMutators(field: IField | FormPathPattern): IMutators -   -  /* -   * Get the form observer tree -   */ -  getFormGraph(): IFormGraph -   -  /* -   * Set the form observer tree -   */ -  setFormGraph(graph: IFormGraph): void -   -  /* -   * Listen to the form life cycle -   */ -  subscribe(callback?: ({ -    type, -    payload -  }: { -    type: string -    payload: any -  }) => void): number -   -  /* -   * Cancel the listening form life cycle -   */ -  unsubscribe(id: number): void -   -  /* -   * Trigger form custom life cycle -   */ -  notify: (type: string, payload?: T) => void -   -  /* -   * Set the field value -   */ -  setFieldValue(path?: FormPathPattern, value?: any): void -   -  /* -   * Get the field value -   */ -  getFieldValue(path?: FormPathPattern): any -   -  /* -   * Set the initial value of the field -   */ -  setFieldInitialValue(path?: FormPathPattern, value?: any): void -   -  /* -   * Get the initial value of the field -   */ -  getFieldInitialValue(path?: FormPathPattern): any + /* + * Form submission, if the callback parameter returns Promise, + * Then the entire submission process will hold and load is true. + * Wait for Promise resolve to trigger the form onFormSubmitEnd event while loading is false + */ + submit( + onSubmit?: (values: IFormState['values']) => any | Promise + ): Promise<{ + Validated: IFormValidateResult + Payload: any //onSubmit callback function return value + }> + /* + * Clear the error message, you can pass the FormPathPattern to batch or precise control of the field to be cleared. + * For example, clearErrors("*(aa,bb,cc)") + */ + clearErrors: (pattern?: FormPathPattern) => void + /* + * Get status changes, mainly used to determine which states in the current life cycle have changed in the form lifecycle hook. + * For example, hasChanged(state,'value.aa') + */ + hasChanged( + target: IFormState | IFieldState | IVirtualFieldState, + path: FormPathPattern + ): boolean + /* + * Reset form + */ + reset(options?: { + // Forced to empty + forceClear?: boolean // Forced check + validate?: boolean // Reset range for batch or precise control of the field to be reset + selector?: FormPathPattern + //clear initialValue + clearInitialValue?: boolean + }): Promise + /* + * Validation form + */ + validate( + path?: FormPathPattern, + options?: { + // Is it pessimistic check, if the current field encounters the first verification error, stop the subsequent verification process + first?: boolean + } + ): Promise + /* + * Set the form status + */ + setFormState( // Operation callback + callback?: (state: IFormState) => any, // No trigger the event + silent?: boolean + ): void + /* + * Get form status + */ + getFormState( //transformer + callback?: (state: IFormState) => any + ): any + /* + * Set the field status + */ + setFieldState( // Field path + path: FormPathPattern, // Operation callback + callback?: (state: IFieldState) => void, // No trigger the event + silent?: boolean + ): void + /* + * Get the field status + */ + getFieldState( // Field path + path: FormPathPattern, // Transformer + callback?: (state: IFieldState) => any + ): any + /* + * Registration field + */ + registerField(props: { + // Node path + path?: FormPathPattern // Data path + name?: string // Field value + value?: any // Field multi-value + values?: any[] // Field initial value + initialValue?: any // Field extension properties + props?: any // Field check rule + rules?: ValidatePatternRules[] // Field is required + required?: boolean // Is the field editable? + editable?: boolean // Whether the field is dirty check + useDirty?: boolean // Field state calculation container, mainly used to extend the core linkage rules + computeState?: (draft: IFieldState, prevState: IFieldState) => void + }): IField + /* + * Register virtual fields + */ + registerVirtualField(props: { + // Node path + path?: FormPathPattern // Data path + name?: string // Field extension properties + props?: any // Whether the field is dirty check + useDirty?: boolean // Field state calculation container, mainly used to extend the core linkage rules + computeState?: (draft: IFieldState, prevState: IFieldState) => void + }): IVirtualField + /* + * Create a field data operator, which will explain the returned API in detail later. + */ + createMutators(field: IField | FormPathPattern): IMutators + /* + * Get the form observer tree + */ + getFormGraph(): IFormGraph + /* + * Set the form observer tree + */ + setFormGraph(graph: IFormGraph): void + /* + * Listen to the form life cycle + */ + subscribe( + callback?: ({ type, payload }: { type: string; payload: any }) => void + ): number + /* + * Cancel the listening form life cycle + */ + unsubscribe(id: number): void + /* + * Trigger form custom life cycle + */ + notify: (type: string, payload?: T) => void + /* + * Set the field value + */ + setFieldValue(path?: FormPathPattern, value?: any): void + /* + * Get the field value + */ + getFieldValue(path?: FormPathPattern): any + /* + * Set the initial value of the field + */ + setFieldInitialValue(path?: FormPathPattern, value?: any): void + /* + * Get the initial value of the field + */ + getFieldInitialValue(path?: FormPathPattern): any } ``` - -#### Imutators - - +#### Imutators > The instance API created by crewikiutators is mainly used to operate field data. - - ```typescript interface IMutators { // Changing the field value and multi parameter condition will store all parameters in values @@ -2732,18 +2916,18 @@ interface IMutators { // Get focus, trigger active state change focus(): void // Lose focus, trigger active / visited status change - blur (): void + blur(): void // Trigger current field verifier validate(): Promise // Whether the value of the current field exists in the values property of form - exist (index?: number | string): Boolean + exist(index?: number | string): Boolean /**Array operation method**/ // Append data push(value?: any): any[] // Pop up tail data - pop (): any[] + pop(): any[] // Insert data insert(index: number, value: any): any[] // Delete data @@ -2761,7 +2945,6 @@ interface IMutators { } ``` - #### IFormActions ```typescript @@ -2904,7 +3087,7 @@ interface IFormAsyncActions { //select field to reset selector?: FormPathPattern //clear initialValue - clearInitialValue?:boolean + clearInitialValue?: boolean }): Promise /* * Get status changes, mainly used to determine which states in the current life cycle have changed in the form lifecycle hook. @@ -3058,7 +3241,6 @@ interface IVirtualFieldState { ### IFormSpyProps ```typescript - interface IFormSpyProps { selector?: string[] | string reducer?: ( @@ -3068,47 +3250,38 @@ interface IFormSpyProps { ) => any children?: React.ReactElement | ((api: IFormSpyAPI) => React.ReactElement) } - ``` - ### IFieldHook ```typescript - interface IFieldHook { form: IForm state: IFieldState props: {} mutators: IMutators } - ``` - ### IVirtualFieldHook ```typescript - interface IVirtualFieldHook { form: IForm state: IFieldState props: {} } - ``` ### ISpyHook ```typescript - interface ISpyHook { form: IForm state: IFieldState props: {} mutators: IMutators } - ``` #### SyncValidateResponse @@ -3220,7 +3393,6 @@ declare type ValidatePatternRules = | ValidateArrayRules ``` - #### IFieldAPI ```typescript diff --git a/packages/react/README.zh-cn.md b/packages/react/README.zh-cn.md index 8e489211377..6e5451de692 100644 --- a/packages/react/README.zh-cn.md +++ b/packages/react/README.zh-cn.md @@ -181,18 +181,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -300,18 +306,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -392,18 +404,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -451,18 +469,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -555,29 +579,41 @@ ReactDOM.render(, document.getElementById('root')) #### display visible -示例: display 与 visible 对values的影响 +示例: display 与 visible 对 values 的影响 ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, LifeCycleTypes, FormSpy } from '@formily/react' +import { + Form, + Field, + createFormActions, + LifeCycleTypes, + FormSpy +} from '@formily/react' const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -586,14 +622,24 @@ const CheckedField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : { - mutators.change(!state.value) - }} checked={!!state.value} /> } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + { + mutators.change(!state.value) + }} + checked={!!state.value} + /> + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -605,50 +651,57 @@ const App = () => { actions={actions} effects={($, { validate, setFieldState }) => { $(LifeCycleTypes.ON_FORM_INIT).subscribe(() => { - setFieldState('displayTrigger', state => state.value = true) - setFieldState('visibleTrigger', state => state.value = true) - setFieldState('a', state => state.value = 1) - setFieldState('b', state => state.value = 2) + setFieldState('displayTrigger', state => (state.value = true)) + setFieldState('visibleTrigger', state => (state.value = true)) + setFieldState('a', state => (state.value = 1)) + setFieldState('b', state => (state.value = 2)) }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'visibleTrigger').subscribe((fieldState) => { - setFieldState('a', state => { - state.visible = fieldState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'visibleTrigger').subscribe( + fieldState => { + setFieldState('a', state => { + state.visible = fieldState.value + }) + } + ) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'displayTrigger').subscribe((fieldState) => { - setFieldState('b', state => { - state.display = fieldState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'displayTrigger').subscribe( + fieldState => { + setFieldState('b', state => { + state.display = fieldState.value + }) + } + ) }} >
- + - +
- - + +
{({ state, form }) => { - return ( -
-              {JSON.stringify(form.getFormState(state => state.values), null, 2)}
-            
-
) + return ( + +
+                {JSON.stringify(
+                  form.getFormState(state => state.values),
+                  null,
+                  2
+                )}
+              
+
+ ) }}
- @@ -661,7 +714,7 @@ ReactDOM.render(, document.getElementById('root')) #### 简单联动 -示例:显示及隐藏,修改props和value +示例:显示及隐藏,修改 props 和 value ```jsx import React from 'react' @@ -672,18 +725,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -692,14 +751,24 @@ const CheckedField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : { - mutators.change(!state.value) - }} checked={!!state.value} /> } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + { + mutators.change(!state.value) + }} + checked={!!state.value} + /> + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -711,16 +780,18 @@ const App = () => { actions={actions} effects={($, { setFieldState }) => { $(LifeCycleTypes.ON_FORM_INIT).subscribe(() => { - setFieldState('a~', state => state.visible = false) + setFieldState('a~', state => (state.visible = false)) }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((triggerState) => { - setFieldState('a~', state => { - state.visible = triggerState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe( + triggerState => { + setFieldState('a~', state => { + state.visible = triggerState.value + }) + } + ) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe((fieldState) => { + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe(fieldState => { setFieldState('a-copy', state => { state.value = fieldState.value }) @@ -754,18 +825,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -773,14 +850,24 @@ const CheckedField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : { - mutators.change(!state.value) - }} checked={!!state.value} /> } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + { + mutators.change(!state.value) + }} + checked={!!state.value} + /> + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -789,20 +876,28 @@ const SelectField = props => ( {({ state, mutators }) => { const { loading, dataSource = [] } = state.props - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -813,8 +908,12 @@ const App = () => {
{ - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((fieldState) => { - const dataSource = [{ label: 'aa', value: 'aa' }, { label: 'bb', value: 'bb' } ] + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe( + fieldState => { + const dataSource = [ + { label: 'aa', value: 'aa' }, + { label: 'bb', value: 'bb' } + ] setFieldState('sync-source', state => { state.props.dataSource = fieldState.value ? dataSource : [] }) @@ -828,7 +927,8 @@ const App = () => { state.props.dataSource = fieldState.value ? dataSource : [] }) }, 300) - }) + } + ) }} > @@ -847,7 +947,7 @@ ReactDOM.render(, document.getElementById('root')) #### 联动校验 -示例:初始化校验,字段change时自动重新触发校验 +示例:初始化校验,字段 change 时自动重新触发校验 ```jsx import React from 'react' @@ -858,18 +958,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -884,7 +990,7 @@ const App = () => { validate() }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe((fieldState) => { + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe(fieldState => { setFieldState('a-copy', state => { state.value = fieldState.value }) @@ -893,7 +999,7 @@ const App = () => { >
- +
) @@ -904,7 +1010,7 @@ ReactDOM.render(, document.getElementById('root')) #### 复杂联动 -示例:ArrayField复杂联动 +示例:ArrayField 复杂联动 ```jsx import React from 'react' @@ -915,18 +1021,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -943,86 +1055,97 @@ const App = () => { }) }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((fieldState) => { - setFieldState('userList.*.username', state => { - state.visible = fieldState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe( + fieldState => { + setFieldState('userList.*.username', state => { + state.visible = fieldState.value + }) + } + ) }} > {({ state, mutators }) => { - return + return ( + + ) }}
- + {({ state, mutators }) => { - return ( - - {state.value.map((item, index) => { - return ( -
- - {({ state: innerState, mutators: innerMutator }) => { - return ( - - {Object.keys(innerState.value).map(key => { - if (!innerMutator.exist(key)) return - return ( - - - - ) - })} - - - ) - }} - + return ( + + {state.value.map((item, index) => { + return ( +
+ + {({ state: innerState, mutators: innerMutator }) => { + return ( + + {Object.keys(innerState.value).map(key => { + if (!innerMutator.exist(key)) return + return ( + + + + ) + })} + + + ) + }} + - -
- ) - })} - - -
- ) - }} + +
+ ) + })} + + +
+ ) + }}
@@ -1032,33 +1155,37 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` -#### 复用Effects - -自定义可复用的effects +#### 复用 Effects +自定义可复用的 effects ```jsx import React from 'react' import ReactDOM from 'react-dom' import { Form, Field, createFormActions, FormEffectHooks } from '@formily/react' - const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1066,36 +1193,46 @@ const CheckedField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : { - mutators.change(!state.value) - }} checked={!!state.value} /> } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + { + mutators.change(!state.value) + }} + checked={!!state.value} + /> + )} + {state.errors} + {state.warnings} + + ) }} ) -const { onFormMount$, onFieldValueChange$ } = FormEffectHooks -const getEffects = ()=>{ - const actions = createFormActions() - onFormMount$().subscribe(() => { - actions.setFieldState('a~', state => state.visible = false) - }) +const { onFormMount$, onFieldValueChange$ } = FormEffectHooks +const getEffects = () => { + const actions = createFormActions() + onFormMount$().subscribe(() => { + actions.setFieldState('a~', state => (state.visible = false)) + }) - onFieldValueChange$('trigger').subscribe((triggerState) => { - actions.setFieldState('a~', state => { - state.visible = triggerState.value - }) + onFieldValueChange$('trigger').subscribe(triggerState => { + actions.setFieldState('a~', state => { + state.visible = triggerState.value }) + }) - onFieldValueChange$('a').subscribe((fieldState) => { - actions.setFieldState('a-copy', state => { - state.value = fieldState.value - }) + onFieldValueChange$('a').subscribe(fieldState => { + actions.setFieldState('a-copy', state => { + state.value = fieldState.value }) + }) } const actions = createFormActions() @@ -1121,7 +1258,6 @@ const App = () => { ReactDOM.render(, document.getElementById('root')) ``` - #### combo 字段 示例:combo username 和 age 字段, 更多用法,请点击[FormSpy](#FormSpy)查看 @@ -1136,18 +1272,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1191,25 +1333,37 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, FormSpy, FormProvider } from '@formily/react' +import { + Form, + Field, + createFormActions, + FormSpy, + FormProvider +} from '@formily/react' const actions = createFormActions() const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1252,45 +1406,68 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React, { useState } from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, FormSpy, FormPath } from '@formily/react' +import { + Form, + Field, + createFormActions, + FormSpy, + FormPath +} from '@formily/react' const actions = createFormActions() const App = () => { return ( -
+ {({ state, mutators }) => { - const [start, end] = state.value - return
- - { - mutators.change([e.target.value, end]) - }} /> - - { - mutators.change([start, e.target.value]) - }} /> -
+ return ( +
+ + { + mutators.change([e.target.value, end]) + }} + /> + + { + mutators.change([start, e.target.value]) + }} + /> +
+ ) }}
- + {({ state, form }) => { - return (
- Form values: - -
-                {JSON.stringify(form.getFormState(state => state.values), null, 2)}
-              
-
-
) + return ( +
+ Form values: + +
+                  {JSON.stringify(
+                    form.getFormState(state => state.values),
+                    null,
+                    2
+                  )}
+                
+
+
+ ) }}
@@ -1302,87 +1479,112 @@ ReactDOM.render(, document.getElementById('root')) #### 复杂解构 - ```jsx import React, { useState } from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, FormSpy, FormPath } from '@formily/react' +import { + Form, + Field, + createFormActions, + FormSpy, + FormPath +} from '@formily/react' const actions = createFormActions() const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) - const App = () => { return ( -
+ {({ state, mutators }) => { - return
- -
Field value:
- -
{JSON.stringify(state.value, null, 2)}
-
-
+ }) + }} + > + set value + +
Field value:
+ +
{JSON.stringify(state.value, null, 2)}
+
+
+ ) }} - {({ state, form }) => { - return (
- Form values: - -
-                {JSON.stringify(form.getFormState(state => state.values), null, 2)}
-              
-
-
) + return ( +
+ Form values: + +
+                  {JSON.stringify(
+                    form.getFormState(state => state.values),
+                    null,
+                    2
+                  )}
+                
+
+
+ ) }}
@@ -1485,18 +1687,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1652,13 +1860,9 @@ const App = () => { ) }} - -
@@ -1711,18 +1915,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1801,25 +2011,37 @@ interface IFormSpyProps { ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, FormSpy, LifeCycleTypes } from '@formily/react' +import { + Form, + Field, + createFormActions, + FormSpy, + LifeCycleTypes +} from '@formily/react' const actions = createFormActions() const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1846,7 +2068,6 @@ const App = () => { } ReactDOM.render(, document.getElementById('root')) - ``` 例子 2:实现常用 combo 组件 @@ -1861,18 +2082,24 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1911,25 +2138,37 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, FormSpy, FormProvider } from '@formily/react' +import { + Form, + Field, + createFormActions, + FormSpy, + FormProvider +} from '@formily/react' const actions = createFormActions() const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -1985,7 +2224,7 @@ interface IFormConsumerProps { #### `useFormEffects` -> 使用 useFormEffects 可以实现局部effect的表单组件,效果同:[简单联动](#简单联动) +> 使用 useFormEffects 可以实现局部 effect 的表单组件,效果同:[简单联动](#简单联动) > 注意:监听的生命周期是从 `ON_FORM_MOUNT` 开始 **签名** @@ -1997,25 +2236,37 @@ interface IFormConsumerProps { ```jsx import React from 'react' import ReactDOM from 'react-dom' -import { Form, Field, createFormActions, useFormEffects, LifeCycleTypes } from '@formily/react' +import { + Form, + Field, + createFormActions, + useFormEffects, + LifeCycleTypes +} from '@formily/react' const actions = createFormActions() const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -2024,14 +2275,24 @@ const CheckedField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : { - mutators.change(!state.value) - }} checked={!!state.value} /> } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + { + mutators.change(!state.value) + }} + checked={!!state.value} + /> + )} + {state.errors} + {state.warnings} + + ) }} ) @@ -2039,16 +2300,18 @@ const CheckedField = props => ( const FormFragment = () => { useFormEffects(($, { setFieldState }) => { $(LifeCycleTypes.ON_FORM_INIT).subscribe(() => { - setFieldState('a~', state => state.visible = false) + setFieldState('a~', state => (state.visible = false)) }) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe((triggerState) => { - setFieldState('a~', state => { - state.visible = triggerState.value - }) - }) + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'trigger').subscribe( + triggerState => { + setFieldState('a~', state => { + state.visible = triggerState.value + }) + } + ) - $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe((fieldState) => { + $(LifeCycleTypes.ON_FIELD_VALUE_CHANGE, 'a').subscribe(fieldState => { setFieldState('a-copy', state => { state.value = fieldState.value }) @@ -2070,9 +2333,7 @@ const FormFragment = () => { const App = () => { return ( -
+ ) @@ -2083,7 +2344,7 @@ ReactDOM.render(, document.getElementById('root')) #### `useFormState` -> 使用 useFormState 为自定义组件提供FormState扩展和管理能力 +> 使用 useFormState 为自定义组件提供 FormState 扩展和管理能力 **签名** @@ -2096,8 +2357,12 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { Form, Field, VirtualField, - createFormActions, createEffectHook, +import { + Form, + Field, + VirtualField, + createFormActions, + createEffectHook, useForm, useFormState, useFormEffects, @@ -2109,33 +2374,45 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) const actions = createFormActions() -const FormFragment = (props) => { - const [formState, setFormState ] = useFormState({ extendVar: 0 }) +const FormFragment = props => { + const [formState, setFormState] = useFormState({ extendVar: 0 }) const { extendVar } = formState - return
- -
count: {extendVar}
-
+ return ( +
+ +
count: {extendVar}
+
+ ) } const App = () => { @@ -2162,8 +2439,12 @@ ReactDOM.render(, document.getElementById('root')) ```jsx import React, { useRef } from 'react' import ReactDOM from 'react-dom' -import { Form, Field, VirtualField, - createFormActions, createEffectHook, +import { + Form, + Field, + VirtualField, + createFormActions, + createEffectHook, useForm, useFormEffects, useFieldState, @@ -2174,30 +2455,36 @@ const InputField = props => ( {({ state, mutators }) => { const loading = state.props.loading - return - { props.label && } - { loading ? ' loading... ' : } - {state.errors} - {state.warnings} - + return ( + + {props.label && } + {loading ? ( + ' loading... ' + ) : ( + + )} + {state.errors} + {state.warnings} + + ) }} ) const changeTab$ = createEffectHook('changeTab') const actions = createFormActions() -const TabFragment = (props) => { - const [fieldState, setLocalFieldState ] = useFieldState({ current: 0 }) +const TabFragment = props => { + const [fieldState, setLocalFieldState] = useFieldState({ current: 0 }) const { current } = fieldState const { children, dataSource, form } = props - const update = (cur) => { + const update = cur => { form.notify('changeTab', cur) setLocalFieldState({ current: cur @@ -2211,43 +2498,55 @@ const TabFragment = (props) => { }) }) - changeTab$().subscribe((idx) => { + changeTab$().subscribe(idx => { dataSource.forEach((item, itemIdx) => { - setFieldState(item.name, state => { - state.display = itemIdx === idx + setFieldState(item.name, state => { + state.display = itemIdx === idx + }) }) }) - }) }) const btns = dataSource.map((item, idx) => { - const focusStyle = idx === current ? { color: '#fff', background: 'blue' } : {} - return + const focusStyle = + idx === current ? { color: '#fff', background: 'blue' } : {} + return ( + + ) }) return btns } -const FormTab = (props) => { - return - {({ form }) => { - return - }} - +const FormTab = props => { + return ( + + {({ form }) => { + return + }} + + ) } const App = () => { return (
- +
- - + +
) @@ -2299,15 +2598,19 @@ type useField = (options: IFieldStateUIProps): IFieldHook ```typescript import { useField } from '@formily/react' -const FormFragment = (props) => { - const { - form, - state, - props: fieldProps, - mutators - } = useField({ name: 'username' }) +const FormFragment = props => { + const { form, state, props: fieldProps, mutators } = useField({ + name: 'username' + }) - return + return ( + + ) } ``` @@ -2326,16 +2629,16 @@ type UseVirtualField = (options: IVirtualFieldStateProps): IVirtualFieldHook ```typescript import { UseVirtualField } from '@formily/react' -const FormFragment = (props) => { - const { - form, - state, - props: fieldProps, - } = UseVirtualField({ name: 'username' }) +const FormFragment = props => { + const { form, state, props: fieldProps } = UseVirtualField({ + name: 'username' + }) - return
- {props.children} -
+ return ( +
+ {props.children} +
+ ) } ``` @@ -2353,27 +2656,25 @@ type useFormSpy = (props: IFormSpyProps): ISpyHook ```typescript import { useFormSpy, LifeCycleTypes } from '@formily/react' -const FormFragment = (props) => { - const { - form, - state, - type, - } = useFormSpy({ +const FormFragment = props => { + const { form, state, type } = useFormSpy({ selector: LifeCycleTypes.ON_FORM_VALUES_CHANGE, reducer: (state, action, form) => ({ count: state.count ? state.count + 1 : 1 }) }) - return
-
count: {state.count || 0}
-
+ return ( +
+
count: {state.count || 0}
+
+ ) } ``` ### API -> 整体完全继承@formily/core, 下面只列举@formily/react的特有API +> 整体完全继承@formily/core, 下面只列举@formily/react 的特有 API --- @@ -2477,10 +2778,9 @@ const App = () => { } ``` - #### createEffectHook -> 自定义hook +> 自定义 hook **签名** @@ -2502,21 +2802,29 @@ const App = () => {
{ - diyHook1$().subscribe((payload) => { + diyHook1$().subscribe(payload => { console.log('diy1 hook triggered', payload) }) - diyHook2$().subscribe((payload) => { + diyHook2$().subscribe(payload => { console.log('diy2 hook triggered', payload) }) }} > - - + +
) } @@ -2526,7 +2834,7 @@ ReactDOM.render(, document.getElementById('root')) ### Interfaces -> 整体完全继承@formily/core, 下面只列举@formily/react的特有的Interfaces +> 整体完全继承@formily/core, 下面只列举@formily/react 的特有的 Interfaces --- @@ -2574,7 +2882,7 @@ interface IForm { //重置范围,用于批量或者精确控制要重置的字段 selector?: FormPathPattern //是否清空默认值 - clearInitialValue?:boolean + clearInitialValue?: boolean }): Promise /* @@ -2726,7 +3034,6 @@ interface IForm { } ``` - #### Imutators > 通过 createMutators 创建出来的实例 API,主要用于操作字段数据 @@ -2809,7 +3116,7 @@ interface IFormActions { //重置范围,用于批量或者精确控制要重置的字段 selector?: FormPathPattern //是否清空默认值 - clearInitialValue?:boolean + clearInitialValue?: boolean }): Promise /* @@ -2936,7 +3243,7 @@ interface IFormAsyncActions { //重置范围,用于批量或者精确控制要重置的字段 selector?: FormPathPattern //是否清空默认值 - clearInitialValue?:boolean + clearInitialValue?: boolean }): Promise /* * 获取状态变化情况,主要用于在表单生命周期钩子内判断当前生命周期中有哪些状态发生了变化, @@ -3106,7 +3413,6 @@ interface IVirtualFieldState { ### IFormSpyProps ```typescript - interface IFormSpyProps { selector?: string[] | string reducer?: ( @@ -3116,44 +3422,37 @@ interface IFormSpyProps { ) => any children?: React.ReactElement | ((api: IFormSpyAPI) => React.ReactElement) } - ``` ### IFieldHook ```typescript - interface IFieldHook { form: IForm state: IFieldState props: {} mutators: IMutators } - ``` ### IVirtualFieldHook ```typescript - interface IVirtualFieldHook { form: IForm state: IFieldState props: {} } - ``` ### ISpyHook ```typescript - interface ISpyHook { form: IForm state: any type: string } - ``` #### SyncValidateResponse @@ -3265,7 +3564,6 @@ declare type ValidatePatternRules = | ValidateArrayRules ``` - #### IFieldAPI ```typescript diff --git a/packages/shared/README.md b/packages/shared/README.md index 4cceaf1d734..1c8f75d88a9 100644 --- a/packages/shared/README.md +++ b/packages/shared/README.md @@ -1,2 +1,3 @@ # @formily/shared -> Formily工具函数集 \ No newline at end of file + +> Formily 工具函数集 diff --git a/packages/validator/README.md b/packages/validator/README.md index 35bb6eb42ac..ad81be4fbee 100644 --- a/packages/validator/README.md +++ b/packages/validator/README.md @@ -1,2 +1,3 @@ # @formily/validator -> Formily数据校验工具 \ No newline at end of file + +> Formily 数据校验工具