FormChef中不会直接引入lib中的FormDish，因为FormDish是实际的表单渲染高阶组件，需要配置过后才可以正常使用。
之所以不在代码级别区分H5和web或者其他场景的, 主要为如下原因

1. FormDish的设计是脱离视觉层的，具体的视觉层，应该由使用者决定，只要符合FormDish的开发规范，Field都可以在FormDish中使用
2. 代码层不会预先引入不必要的文件，如果提前定义H5和web的组件，那么在具体的业务前端工程中，代码的打包就会出现大量的非必要代码，比如：H5中出现web端的field组件代码，web中出现H5的field组件代码。

### FormChef, FormDish, FormFood, Field的关系

1. FormChef主要是控制表单的内在运行机制（还是包含了少量UI的控制，比如墓碑图，web端的元素布局控制）
2. FormDish负责控制Field,FormFood的入口，保持一致性的逻辑规则，约束使用者对入口参数的过度滥用。
3. Field是具体的某个表单子组件，比如DatePicker,MoneyInput等
4. FormFood是Field的直接父组件（也可以理解卫Field的wrapper组件），WebFormFood就是一种FormFood组件，是business提供给web端使用的。FormFood组件必须通过FormDish生成。也就是说你可以不用WebFormFood,可以自行开发，但必须受到FormDish的约束，根据Field容器的规则开发。

----

> FormFood的可定制设计，一是为了解决H5端和Web端在UI层的不一致，同时也增加实现层的灵活度。

#### start up

```js static
//step1:
FormDish((<FormFood><Field /></FormFood>)
//step2
async ()=>{

    await formInstantiate(formScheme);
    /* initData接受2个参数；data：初始化的数据，在具体业务场景，data可能是后端返回的具体表单数据，也可能是上下文需要带入的预定义的数据，比如某种情况下，需要从上文的操作中带入一些数据，比如具体的报销场景，发票生成费用；第二个参数为保单*/
    initData(data,true);

}
//或者
formInstantiate(formScheme).then(()=>{

    initData(data,true);

})

``` 

#### demo

##### 1-简单的表单

```jsx
import fieldMaps from '../FormFields';
import Demo1 from './demo/Demo1';
(<Demo1 />)
```

##### 2-表单联动

``` jsx
import fieldMaps from '../FormFields';
import Demo2 from './demo/Demo2';
(<Demo2 />)
```

### API参考

#### FormChef接口说明

|name|说明|其他|
|--|--|--|
|form|formchef传入子组件的表单功能集合||

##### form属性说明

|name|说明|类型|备注|
|--|--|--|--|--|
|initData|初始化表单数据|function(data, isNew)|data：预定义数据，isNew: 表单是否新建标识，决定了表单是否生成默认值|
|formInstantiate|表单实例化过程，解析表单配置，生成field对象，公式依赖，数据池等基础数据|function|接收一个参数，为表单的描述scheme|
|setWatch|定义观察函数，用于触发某个观察值变动后所触发的动作|function||
|setFieldsValue|设置field的值|function||
|getFieldDecorator|定义基础的formChef field|function||
|getFieldError|获取某个field的错误信息|function||
|validateFields|校验表单的有效性|||
|rebuildForm|重构表单|||
|getFieldValue|获取某个field的值|||
|fetchFormData|获取表单数据|||
|cookForm|表单统一生成的函数，根据表单配置信息，标准输入表单个元素|function||

#### setFieldsValue函数参数说明

setFieldsValue(changeValues, modifyOption)
|name|说明|类型|备注|
|--|--|--|--|
|changeValues|field修改的对象|{}|{key:value}|
|modifyOption||{ blockChangeEffect, modifyFromProps, blockValidate}|{key:value}|

```js static
{

    blockChangeEffect.//阻断连续影响，主要体现在联动触发上
    modifyFromProps,//阻断来自props的数值跟新，主要体现在子表单中，父组件的props改变，默认映射child的fieldvalue，但是又不想这类更改导致整个formchef的rerender
    blockValidate,//阻断校验，在不需要检验的时候可以传入此参数，比如设置默认值

}
```

#### 条件变更

说明：条件变更是指表单的某些字段，需要根据其他字段的值来控制是否存在/隐藏/可读性/校验规则（已知的有必填性）等表单属性，条件需依赖formchef提供的表单配置更新方法(<b>updateFormFields</b>)实现。

#### ❗表单联动机制

表单的联动在复杂的表单中非常常见，但也是最容易引起性能上的问题，表单联动规则需通过正常、通用、逻辑自洽的方式生产，不可通过具体的项目需求做特殊化定制。
表单联动规则分为同步联动和异步联动，异步联动主要指表单的联动需要发起ajax请求获取数据的案例。<br/>
表单联动执行规则如下：<br/>

1. 同步异步混合执行。
2. 条件变动和watch函数需要在所有数据联动结束后执行。
3. 一次拓扑排序理论上能把所有的影响到的字段都执行完成。（联动的代码中加入循环依赖的检测，防止出现死循环的情况）

***一次变更周期，根据联动的额外效应和js的单进程运行机制，同步必然比异步先执行，所以从性能优化角度看，统一处理同步联动，然后处理异步联动，在逻辑上可控，性能上更优。***

##### 联动规则数据模型

联动规则的数据模型参阅[formChefParser数据关系规则数据模型](/#formchefcommon)

#### 表单字段隐藏

说明：仅仅在UI层面控制不显示，其他逻辑一切不变

#### 表单字段销毁

说明：字段销毁，相关的表单内逻辑等一切都跟随移除

##### 注意事项：

1. 表单联动（包含公式），只在编辑模式下有效，查看模式下无效（暂时）
