react-schema-form
爬虫前端核心组件。
DEMO
react-schema-form-react V3
通过json-schema,ui-schema,自动生成表单组件。前后端可以复用一份JsonSchema来验证字段,错误消息前后端统一,这个可以有。
Note: 组件之间的功能组合使用hoc来实现。
目录
安装
npm
npm install --save fx-schema-form-react
依赖项
- react
- redux
- react-redux
- immutable
- recompose
- ajv
- reselect
- redux-act
- resolve-pathname
- redux-immutable
Note: 请根据自己的项目情况选择使用。
性能
这里。更改一下数据,触发错误信息;以下是Schema和图片:
默认使用
导入fx-schema-form-react的依赖
; ;
实例化ajv
;
创建store,初始化schemaform的reducer
这里的reducer的key是可以自定义的。从工厂类中获取schemaForm这个类;schemaForm是默认定义的reducer,可以自定义reducer来覆盖;
;
将schemaform的actions添加到store
这里的actions注册到store就可以直接使用,不需要在使用dispatch来触发action。
;for in actions
加入template和widget
defaultThemetempFactory;defaultThemetempFactory;defaultThemetempFactory; defaultThemewidgetFactory;defaultThemewidgetFactory;defaultThemewidgetFactory;
创建表单组件
/** * SchemaForm的Hoc * 加入了 * data 当前表单的数据,实时更新。 * root 当前表单的meta根节点。 * isValid 当前表单验证是否正确。 * isValidating 当前表单是否正在验证。 * errors 当前表单的所有错误信息。 */@ as anyPureComponent<any> /** * @param RootComponent 使用Form来创建根元素 * @param schemaId schema的id是design * @param uiSchemas 需要渲染的表单元素 * @param uiSchema 父亲uiSchema * @param parentKeys 数据节点的根Keys,一般就等于crateForm中的key * @param globalOptions 全局的配置 * @param ajv ajv的实例 */ public { const isValidating = false isValid = false validateAll parentKeys resetForm schemaId } = thisprops; if !thispropsroot return null; return <> <FormComponent = = = = = = = = = > </FormComponent> </>; }
实例化SchemaForm组件
ReactDOM;
表单定制化
全局配置参数
默认分为3块内容:
- field: 所有的field的参数配置在此;
- temp: 所有的模板的参数配置在此;
- hoc: 所有的hoc的参数配置在此;
const gloabelOptions = Immutable
UiSchema配置
uiSchema的参数配置:
- options?: Immutable.Map<string, any>; 定义参数,与全局的配置参数格式一致;会覆盖全局的配置参数,用于单个FormSchemaItem的配置。
- children?: Array<UiSchema | string>; 一般用于object和array的对象;用于渲染下级显示的key。
- theme?: string; 主题样式配置(default: default)。
- field?: string; 定义字段。默认使用JsonSchema的type来确定field,也可以使用这个来指定字段。
- widget?: string; 定义显示组件。每种数据类型都可以使用不同的组件来渲染。
- temps?: string[]; 定义包裹的模板数组。
- isRequired?: boolean; 是否是required,自动添加。
- readonly?: boolean; 是否是只读的。
- hocs?:Array<string | ComponentEnhancer>; 用于包裹整个ShemaFormItem的hoc数组。(default:["theme", "field", "validate", "array", "temp"])
模板
模板是一个用来包裹Widget的组件(例如:Div、Row、Col、Card、FormItem等,其中Card和FormItem需要显示错误信息或者当前状态,所以需要加入hoc来获取数据,这个配置在全局配置中的temp一节)
HOCS
名称 | 说明 | 依赖 | 加入属性 |
---|---|---|---|
ThemeHoc | 解决主题样式 | null | currentTheme |
FieldHoc | 取得FieldComponent和WidgetComponent | ThemeHoc, UtilsHoc | FieldComponent,WidgetComponent |
ValidateHoc | 验证以及数据操作相关 | null | updateItemData,updateItemMeta,validate |
ArrayHoc | 数组的相关操作 | UtilsHoc | addItem,removeItem,moveItem,initArrayComponent,ArrayComponent,ArrayItemComponent |
TempHoc | 模板的归并 | ThemeHoc, UtilsHoc, [ArrayHoc] | null |
DataHoc | 用于从reducer中获取数据 | UtilsHoc | [formItemData,formItemMeta,formItemNode] |
MakeHoc | 用于FormItem的包裹Hoc合并 | UtilsHoc | null |
UtilsHoc | 工具类Hoc | null | getOptions,getTitle,getPathKeys,normalizeDataPath,getRequiredKeys |
MergeHoc | jsonschema和uischema合并 | null | null |
ThemeHoc
配置参数: null
返回属性:
- currentTheme: NsFactory 获取当前的主题样式工厂类;
FieldHoc
配置参数: null
返回属性:
- FieldComponent: new() => React.PureComponent; 根据schema的配置获取对应的FieldComponent
- WidgetComponent: new() => React.PureComponent; 根据schema的配置来获取对应的WidgetComponent
ValidateHoc
配置参数: null
返回属性:
- updateItemData: (props, data, meta?) => void; 提交数据,触发更改数据action
- updateItemMeta: (props, data, meta?, noChange?) => void; 提交meta数据,触发更改meta的action
- removeItemData: (props, meta?) => void; 删除当前数据和meta数据
- validate: (props, data, meta) => any; 验证data的合法性
ArrayHoc
配置参数: null
返回属性:
- addItem: (props,data) => Promise; 数组中添加一项到末尾
- removeItem: (parentKeys,keys,index) => void; 数组删除一个元素
- moveItem: (parentKeys,keys,index) => void; 数组中2个元素交换位置
- initArrayComponent: (props,index) => JSX.Element; 根据当前的schema返回ArrayComponent
- ArrayComponent: React.PureComponent; 数组的操作组件
- ArrayItemComponent: React.PureComponent; 数组中子元素的操作组件
TempHoc
配置参数:
- tempField: string; 配置中的字段名称
- templates: string[]; 需要使用的temps
返回属性: null
DataHoc
配置参数:
- data: boolean; 是否需要数据
- dataLength: boolean; 是否需要数据的长度
- meta: boolean; 是否需要meta数据
- metaKeys: string[]; meta数据中的字段过滤
- treeNode: boolean; 是否需要treeNode
返回属性:
- formItemData: any; 当前组件的数据
- formItemMeta: Immutable.Map; 当前组件的meta数据
- formItemNode: TreeMap; 当前组件对应的tree
MakeHoc
配置参数:
- hocs: Array<string|ComponentEnhancer>; 需要compose的hoc数组
返回属性: null
UtilsHoc
配置参数: null
返回属性:
- getOptions: (props,category,field,...extraSettings) => Object; 获取当前元素的配置参数
- getTitle: (props,...extraSettings) => string; 获取当前元素的标题
- getPathKeys: (keys,path) => string[]; 获取当前元素keys的相对keys
- normalizeDataPath: (schemaId,dataPath) => string[]; 格式化keys
- getRequiredKeys: (props,include,exclude) => string[]; 获取当前props中所需的prop
- getDefaultData: (ajv,schema,defaultData,merge) => Promise; 获取schema的默认数据
MergeHoc
配置参数: null
返回属性:
- mergeSchemaList: FxUiSchema[]; 合并之后的数组
字段
字段决定了如何渲染一个数据结构。举个栗子:
这里的结构是一个ObjectField对象,所以默认会嵌套一层SchemaForm,然后渲染出x和y的文本框。 如果我想x和y在一行上显示;那这里就要用到自定义的Field,参照自定义Field一节;这里我们自定义一个PointField,在里面直接放入2个文本框,当文本框更改的时候,我们更新相对应的值就可以了,so easy。
默认字段:
NormalField
普通数据类型字段,直接渲染WidgetComponent。
配置项:
- widgetHocs: Array<string|ComponentEnhancer>; 为WidgetComponent包装hoc
ArrayField
根据数组元素的个数,嵌套渲染N个ShemaForm。
配置项:
- formHocs: Array<string|ComponentEnhancer>; 数组根元素包装hocs
- formItemHocs: Array<string|ComponentEnhancer>; 数组中每个元素包装hocs
ObjectField
直接嵌套一层SchemaForm。
配置项:
- formHocs: Array<string|ComponentEnhancer>; 为WidgetComponent包装hoc
高级配置
为了增强功能,很多时候需要自定义一些hoc;
自定义hoc
hoc是schema-form的核心功能;比如接口请求,条件判断,数据处理等等。举个例子:
JsonSchema中有format字段配置,我们想根据format来更改渲染组件。
/** * format装饰器 * 根据指定的format来配置相对应的组件 * 例如:当format=date的时候,使用datetime组件 * @param hocFactory hoc的工厂方法 * @param Component 需要包装的组件 */const hoc = hocFactory: BaseFactory<any> const name = "format"; return return Component: any: RC<Props, > PureComponent<Props, > /** * 渲染组件 */ public : JSXElement | null const uiSchema getOptions = thisprops format field = uiSchema hocOptions = ; // 根据当前jsonschema中配置的format // 查看配置中是否有定义,如果有则合并到uiSchema中 if format && hocOptionsformat && !field Object; return <Component />; return ComponentHoc as any; ; ;;
自定义字段
自定义字段是为了解决一些特殊的数据格式。比如我们有以下数据结构:
这里是一个树形结构,如果我们想渲染成tree。默认的ArrayField显然不能满足需求。具体请查看源码
这里使用了3个Form组件,只是使用的field不同。
自定义模板
为了满足不同的样式,不同的需求,需要各种各样的模板组件。
自定义组件
为了满足不同的样式组件,这里需要自己建立很多的模组件,比如(input,select,mension...);
验证
本地验证
本地验证,直接使用json-schema的各种关键字来定义。
当然也可以自定义一些验证,关于自定义验证请查看这里
远程验证
ajv默认支持远程验证,文档在这里