@ formatily/ react-schema- relander (英语)
页:1 简体中文
Schema渲染引擎,软件包主要依靠@formily/resact,其责任非常简单,核心做两件事:
- 分析窗体外观协议, 递归渲染
- 管理自定义组件
安装
npm install --save @formily/react-schema-renderer
目录
- 使用量
- 高级教程
- API 密码
- 类
- 新 Schema( json : ISchema)
getmergegetEmptyValuegetSelfPropsgetExtendsRulesgetExtendsRequiredgetExtendsEditablegetExtendsVisiblegetExtendsDisplaygetExtendsTriggerTypegetExtendsPropsgetExtendsComponentgetExtendsComponentPropsgetExtendsRenderergetExtendsEffectsetPropertysetPropertiessetArrayItemsgetOrderPropertiesmapPropertiestoJSONfromJSONisObjectisArray()
- 新 Schema( json : ISchema)
- 构成部分
- 接口
使用量
快开始
如果您是直接基于 @ formily/ react-schema-render 开发, 那么您必须在开发前注册您的自定义组件 。 去制造器,否则我们的JSON-Schema协议无法制造出表格. 所以说:
import React from 'react'
import {
SchemaForm,
registerFormField,
connect
} from '@formily/react-schema-renderer'
registerFormField(
'string',
connect()(({ value, onChange }) => {
return <input value={value} onChange={onChange} />
})
)
export default () => {
return (
<SchemaForm
schema={{
type: 'object',
properties: {
input: {
type: 'string'
}
}
}}
onChange={console.log} //{input:'this is your input string'}
/>
)
}
伟大的工作技巧,这是最简单的使用方式,核心是注册组件,然后使用协议来渲染.** 需要注意的是,我们在注册组件时使用了连接功能, 此连接函数的功能是允许任何组件在SchemaForm中注册,只要它支持值/onChange API. 同时,连接功能也屏蔽了Field API,因此使用连接功能的组件无法被更强大的扩展. 详细的连接API将在稍后推出. ** 同时,需要指出的是,如果我们想访问一组组件库,该行业的大多数组件库都有其表格和表格项目组件。 他们的核心用于控制样式,Form Project 控件形成本地样式,Form 控制全局形式样式,因此在生产环境中,我们需要注册Form和Form Project 组件,使样式与原始解决方案一致. 我们稍后将详细介绍如何具体登记.
JSON Schema 驱动程序渲染
说到JSON Schema,上述例子已包括在内。 当然,这还不够复杂。 让我们看看一个更复杂的例子:
import React from 'react'
import { SchemaForm } from '@formily/react-schema-renderer'
registerFormField(
'string',
connect()(({ value, onChange }) => {
return <input value={value} onChange={onChange} />
})
)
registerFormField('array', () => {
return //...
})
export default () => {
return (
<SchemaForm
schema={{
type: 'object',
properties: {
array: {
type: 'array',
items: {
type: 'object',
properties: {
input: {
type: 'string'
}
}
}
}
}
}}
onChange={console.log} //{array:[{input:'This is your input string'}]}
/>
)
}
上面的代码是一个伪代码,因为我们没有注册类型数组的自定义组件. 在这里,我们不谈论如何注册数组类型的自定义组件. 我们的核心是分析JSON Schema如何驱动形式渲染. 说明:在SchemaForm中,一个对象的属性的递归渲染是内置的,但没有内置数组的项目的递归渲染. 主要原因是一个阵列的递归渲染涉及许多风格要求,这对内置来说不方便. 所以最好让开发商自己来实施. 因此,我们将详细说明如何执行自动递增列表的递归渲染要求.
JSchema 驱动格式渲染
JSchema在jsx中以更优雅的方式描述了JSON Schema. 我们可以实施JSchema版本的上述例子:
import React from 'react'
import {
SchemaMarkupForm as SchemaForm,
SchemaMarkupField as Field
} from '@formily/react-schema-renderer'
export default () => {
return (
<SchemaForm
onChange={console.log} //{array:[{input:'This is your input string'}]}
>
<Field type="array" name="array">
<Field type="object">
<Field type="string" name="input" />
</Field>
</Field>
</SchemaForm>
)
}
如你所见,使用JSchema在你的代码中描述JSON Schema比JSON更优雅,极大地提高了代码的可维护性.
非单一实例登记部分
在前一个例子中,我们使用注册器Form Fellow API来注册自定义组件,这是注册单通子的方法,它的主要优点是方便,但也有一些问题,即单通子容易被污染,特别是在SPA页面中. 如果不同页面的开发者不同,因为共享相同的内存环境,那么A开发者可能会注册与B开发者同名的自定义组件,这很容易导致在线失败. 因此,我们建议用户使用非单一登记方法:
import React, { useMemo } from 'react'
import {
SchemaForm,
registerFormField,
connect
} from '@formily/react-schema-renderer'
const StringField = connect()(({ value, onChange }) => {
return <input value={value} onChange={onChange} />
})
const useFields = () =>
useMemo(() => {
string: StringField
})
export default () => {
return (
<SchemaForm
fields={useFields()}
schema={{
type: 'object',
properties: {
input: {
type: 'string'
}
}
}}
onChange={console.log} //{input:'this is your input string'}
/>
)
}
在上述例子中,我们主要通过SchemaForm道具维度中的自定义组件,从而可以保证实例级注册. 这种形式对SPA非常友好. 同时,需要注意的是,我们抽象出一个使用Fields的React Hook,它主要用于在组件被多次渲染时解决React Virtual DOM重新计算,从而避免了形式组件被反复渲染.
高级教程
如何访问第三方组成部分图书馆?
由于@formily/react-schema-renderer是一个基础库,因此默认没有组件库集成. 因此,在实际的商务开发中,如果你想根据它定制,就必须面对访问第三方组件库的问题. 如何访问第三方组件库,让我们将其分为以下步骤: 1
- 访问表格/表格项目组件
- 访问组件库窗体组件
- 执行窗体布局组件
- 执行自动递增列表组件
让我们一步一步地进入第三方组件库! 在这里,我们主要以蚂蚁组件库为例.
如何访问表格/表格项目组件?
进入方法目前提供了一个全球登记机制和单一吨登记机制。 全球注册主要使用两个API注册,注册FormCompany和注册FormProjectsCompany. Singleton 注册是直接在 SchemaForm 属性中上传表单 Confonent 和表单项目 Confonent 。 如果是SPA场景,建议采用单通登记法. 让我们看看以下的例子:
import React from 'react'
import {
SchemaForm,
registerFormComponent,
registerFormItemComponent
} from '@formily/react-schema-renderer'
import { Form } from 'antd'
export const CompatFormComponent = ({ children, ...props }) => {
return <Form {...props}>{children}</Form> //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 }) => {
const messages = [].concat(props.errors || [], props.warnings || [])
let status = ''
if (props.loading) {
status = 'validating'
}
if (props.invalid) {
status = 'error'
}
if (props.warnings && props.warnings.length) {
status = 'warning'
}
return (
<Form.Item
{...props}
label={props.schema.title}
help={
messages.length ? messages : props.schema && props.schema.description
}
validateStatus={status}
>
{children}
</Form.Item>
)
}
/***
Global registration method
registerFormComponent(CompatFormComponent)
registerFormItemComponent(CompatFormItemComponent)
***/
//Single case registration method
export default () => {
return (
<SchemaForm
formComponent={CompatFormComponent}
formItemComponent={CompatFormItemComponent}
/>
)
}
我们可以看到,仅通过扩展表单/表单项目组件,就很容易地扩展表单的整体或部分样式。 在此应当指出,表格项目部分收到的道具有些复杂。 别担心,详细的道具API将在稍后列出. 现在我们只需要知道它是怎么注册的.
如何访问窗体组件?
组件库的所有组件都是原子组件,大多数组件都与值/上变规格相兼容,这样我们就可以用连接函数快速访问组件库的组件. 通常,如果我们需要访问组件库组件,我们可能做三件事:
- 处理状态图, 将装入/错误状态在格式中映射到组件属性, 当然, 的前提,即组件必须支持加载或出错等样式.
- 处理细节样式,将格式内的可编辑状态映射到PreviewText组件,以获取更友好更清洁的演示文稿数据.
- 处理组件数, 让我们想想, JSON Schema, 每个节点应该支持 enum 属性,如果我们有enum属性,我们最好以Select的形式显示它,所以我们需要处理组件计数状态.
以输入数为例:
import React from 'react'
import { connect, registerFormField } from '@formily/react-schema-renderer'
import { InputNumber } from 'antd'
const mapTextComponent = (
Target: React.JSXElementConstructor<any>,
props: any = {},
fieldProps: any = {}
): React.JSXElementConstructor<any> => {
const { editable } = fieldProps
if (editable !== undefined) {
if (editable === false) {
return PreviewText
}
}
if (Array.isArray(props.dataSource)) {
return Select
}
return Target
}
const mapStyledProps = (
props: IConnectProps,
fieldProps: MergedFieldComponentProps
) => {
const { loading, errors } = fieldProps
if (loading) {
props.state = props.state || 'loading'
} else if (errors && errors.length) {
props.state = 'error'
}
}
const acceptEnum = (component: React.JSXElementConstructor<any>) => {
return ({ dataSource, ...others }) => {
if (dataSource) {
return React.createElement(Select, { dataSource, ...others })
} else {
return React.createElement(component, others)
}
}
}
registerFormField(
'number',
connect({
getProps: mapStyledProps, //Process state map
getComponent: mapTextComponent //Process details
})(acceptEnum(InputNumber)) //Process enumeration states
)
在这个例子中,我们深入地使用连接函数. 连接是一个HOC。 在渲染阶段,可以给组件渲染过程添加一些中间处理逻辑来帮助动态分布. 当然,连接有很多API,以后会详细报道.
如何处理窗体布局 ?
JSON Schema描述了由自然支持的数据结构的形式. 但形式最终是UI级. 不幸的是,在UI级别上,我们有许多组件不是JSON Schema的特定数据节点. 这只是一个UI节点。 那么,如何在JSON Schema中描述复杂的布局?
现在,Formily的方法是 抽象一个概念,叫做 虚拟节点在用户指定一个JSON Schema x-组件作为代码级的虚拟节点后,无论是渲染,数据处理,还是最终的数据提交,只要节点是虚拟的,它就不会被当作普通的数据节点. 因此,有了这个虚拟节点的概念,我们可以在JSON Schema中描述各种复杂的布局. 让我们试着写一个布局组件:
import React from 'react'
import { SchemaForm, registerVirtualBox } from '@formily/react-schema-renderer'
import { Card } from 'antd'
registerVirtualBox('card', ({ children, ...props }) => {
return <Card {...props.schema.getExtendsComponentProps()}>{children}</Card>
})
export default () => {
return (
<SchemaForm
schema={{
type: 'object',
properties: {
layout_card: {
//layout_cardThe name of this property, whatever you change will not affect the final submitted data structure
type: 'object',
'x-component': 'card',
'x-component-props': {
title: 'This is Card'
},
properties: {
array: {
type: 'array',
items: {
type: 'object',
properties: {
input: {
type: 'string'
}
}
}
}
}
}
}
}}
/>
)
}
从这个伪码中,我们可以看到该卡是一个普通的Object Schema节点,只需要将一个x-组件指定为卡,这样它就能与注册符VirtualBox所注册的卡相匹配,就能实现虚拟节点的效果. 因此,无论JSON Schema中的财产名称有什么变化,都不会影响最终提交的数据结构.在此需要注意的是,x-组件-道具直接被传递到寄存器VirtualBox的回调函数参数. 这是JSON Schema表格的使用,我们也使用JSchema:
import React from 'react'
import { SchemaForm, createVirtualBox } from '@formily/react-schema-renderer'
import { Card } from 'antd'
const Card = createVirtualBox('card', ({ children, ...props }) => {
return <Card {...props}>{children}</Card>
})
export default () => {
return (
<SchemaForm>
<Card title="This is Card">
<Field type="array" name="array">
<Field type="object">
<Field type="string" name="input" />
</Field>
</Field>
</Card>
</SchemaForm>
)
}
从这个例子可以看出,通过创建VirtualBox API,您可以快速创建一个可以直接在JSchema中使用的布局组件.事实上,创建VirtualBox的内部执行非常简单,只需使用注册符VitualBox和SchemaMarkup Field数字 :
import React from 'react'
import { SchemaMarkupField as Field } from '@formily/react-schema-renderer'
export function createVirtualBox<T = {}>(
key: string,
component?: React.JSXElementConstructor<React.PropsWithChildren<T>>
) {
registerVirtualBox(
key,
component
? ({ props, schema, children }) => {
return React.createElement(component, {
...schema.getExtendsComponentProps(),
children
})
}
: () => <Fragment />
)
const VirtualBox: React.FC<T & { name?: string }> = ({
children,
name,
...props
}) => {
return (
<Field
type="object"
name={name}
x-component={key}
x-props={props}
x-component-props={props}
>
{children}
</Field>
)
}
return VirtualBox
}
上述布局组件的注册方式是单吨注册. 如果我们需要以实例形式进行登记,这仍然与我们先前所说的类似.
import React from 'react'
import { Card as AntdCard } from 'antd'
const Card = ({children,...props})=>{
return <AntdCard {...props.schema.getExtendsComponentProps()}>{children}</Card>
}
export default ()=>{
return (
<SchemaForm
virtualFields={{
card:Card
}}
schema={{
type:"object",
properties:{
layout_card:{//layout_cardThe name of this property, whatever you change will not affect the final submitted data structure
type:"object",
"x-component":"card",
"x-component-props":{
title:"This is Card"
},
properties:{
array:{
type:"array",
items:{
type:"object",
properties:{
input:{
type:"string"
}
}
}
}
}
}
}
}}
/>
)
}
如何执行递归渲染组件?
什么是递归渲染组件? 事实上, 执行 JSON Schema 中属性和项目的组件缩写为type:"string" 这种节点属于原子节点,不是递归渲染成分. 上面提到的布局组件,也是一种递归渲染组件,但是它修补了渲染模式,因此很容易被注册. 所以,我们大多数人想要执行 场景的递归渲染, 也许更多的场景 在"类型:"阵列"将执行 递归渲染。 下面将详细介绍自动递减清单部分的执行情况.
如何实施自动递减列表组件?
自我递增列表具有几个主要特征:
- 独立样式
- 支持子组件的递归渲染
- 支持添加、删除、上移、下移数组项目
- 无法被连接函数所包裹, 因为必须调用字段 API
为了帮助您更好地理解如何执行自动递增列表组件,我们将不执行特定的样式,更多的是教你如何执行递归渲染和数组项操作. 让我们看看伪密码:
import React, { Fragment } from 'react'
import {
registerFormField,
SchemaField,
FormPath
} from '@formily/react-schema-renderer'
//No need to pack with connet
registerFormField('array', ({ value, path, mutators }) => {
const emptyUI = (
<button
onClick={() => {
mutators.push()
}}
>
Add Element
</button>
)
const listUI = value.map((item, index) => {
return (
<div key={index}>
<SchemaField path={FormPath.parse(path).concat(index)} />
<button
onClick={() => {
mutators.remove(index)
}}
>
remove
</button>
<button
onClick={() => {
mutators.moveDown(index)
}}
>
move down
</button>
<button
onClick={() => {
mutators.moveUp(index)
}}
>
move up
</button>
</div>
)
})
return value.length == 0 ? emptyUI : listUI
})
实施自递增列表组件,并带有递归渲染功能是超简单的. 相反,实施相关的风格会有点麻烦. 简言之,核心是使用Schema Feld组件和变异体API,具体API将在后作详细描述.
如何执行超复杂自定义组件?
这个问题在旧的形式上是无法解决的。 恰巧,由于我们的业务复杂程度在某种程度上很高,我们受到这个问题的限制,所以我们必须想出办法来解决这个问题. 我们可以定义一个超复杂的定制组件:
-
构件内部有大量的形式成分,内部也有大量的联系关系.
-
组件内部有一个私人服务器动态渲染方案.
-
组件内部有一个复杂的布局结构
在这三点中,满足超复杂自定义组件的特性,对于这个情景,为什么我们不能通过正确封装自定义组件的形式来解决问题? 事实上,它主要局限于核查,没有方法来检查整个,所以我们需要一种能够集成大量场处理逻辑的能力. 让我们来看看具体的解决办法:
import React, { Fragment } from 'react'
import {
registerFormField,
SchemaField,
FormPath,
InternalField,
useFormEffects,
FormEffectHooks
} from '@formily/react-schema-renderer'
import { Input, Form } from 'antd'
const FormItem = ({ component, ...props }) => {
return (
<InternalField {...props}>
{({ state, mutators }) => {
const messages = [].concat(state.errors || [], state.warnings || [])
let status = ''
if (state.loading) {
status = 'validating'
}
if (state.invalid) {
status = 'error'
}
if (state.warnings && state.warnings.length) {
status = 'warning'
}
return (
<Form.Item
{...props}
help={messages.length ? messages : props.help && props.help}
validateStatus={status}
>
{React.createElement(component, {
...state.props,
value: state.value,
onChange: mutators.change,
onBlur: mutators.blur,
onFocus: mutators.focus
})}
</Form.Item>
)
}}
</InternalField>
)
}
//No need to pack with connet
registerFormField('complex', ({ path }) => {
useFormEffects(({ setFieldState }) => {
FormEffectHooks.onFieldValueChange$('ccc').subscribe(({ value }) => {
if (value === '123') {
setFieldState('ddd', state => {
state.value = 'this is linkage relationship'
})
}
})
})
return (
<>
<FormItem name={FormPath.parse(path).concat('aaa')} component={Input} />
<FormItem name={FormPath.parse(path).concat('bbb')} component={Input} />
<FormItem name="ccc" component={Input} />
<FormItem name="ddd" component={Input} />
</>
)
})
在这个伪码中,我们主要使用两个核心API,主要使用Formeffects和InternalField,useFormeffects给开发者一个局部写出效果逻辑的地方,这样效果逻辑就可以轻松地被再用. 内部字段为 @ formaly/ react 字段 。 您可以查看 @formaly/ react 文档 。 SchemaForm在内部也使用@formily/react,它可以共享相同的上下文,这样我们就可以在自定义组件内轻松地使用内域. 还注意到 当直接使用内域时,我们注册的名称是根级别名称,如果想要重用当前自定义组件的路径,您可以使用FormPath解决路径,然后集合.
API 密码
总体API完全继承了@formily/core和@formily/react,下文仅列出@formily/react-schema-render的具体API.
连接
自定义组件注册桥,一个高级组件功能(HOC),主要用于快速访问大多数组件库组件(执行值值/变化 API的组件)
签署
connect(options?: IConnectOptions): (component : React.JSXElementConstructor<any>)=>(fieldProps:ISchemaFieldComponentProps)=>JSX.Element
使用量
import { registerFormField, connect } from '@formily/react-schema-renderer'
import { Select } from 'antd'
registerFormField('select', connect()(Select))
注册表格字段
注册自定义组件功能
签署
registerFormField(
name:string,
component: React.JSXElementConstructor<ISchemaFieldComponentProps>
)
注册格式字段
定制组件的大宗登记
签署
registerFormFields(
fieldsMap: {
[key : string]: React.JSXElementConstructor<ISchemaFieldComponentProps>
}
)
注册格式组件
注册窗体样式组件
签署
registerFormComponent<Props>(
component:React.JSXElementConstructor<Props>
)
注册格式项目组件
注册窗体项目样式组件
签署
registerFormItemComponent(
component:React.JSXElementConstructor<ISchemaFieldComponentProps>
)
虚拟框
注册虚拟框组件,主要用于描述 JSON Schema 中的布局
签署
registerVirtualBox(
name:string,
component:React.JSXElementConstructor<ISchemaVirtualFieldComponentProps>
)
创建虚拟框
创建虚拟框组件, 返回的组件可以直接用于 SchemaMarkupForm
签署
createVirtualBox<Props>(
name:string,
component:React.JSXElementConstructor<Props>
) : React.FC<Props>
使用量
import React from 'react'
import {
SchemaMarkupForm as SchemaForm,
SchemaMarkupField as Field,
createVirtualBox
} from '@formily/react-schema-renderer'
import { Card } from 'antd'
const FormCard = createVirtualBox('card', props => {
return <Card {...props} />
})
export default () => (
<SchemaForm>
<FormCard title="This is card">
<Field name="aaa" type="string" />
</FormCard>
</SchemaForm>
)
创建控制器框
创建虚拟框组件, 返回的组件可以直接用于 Schema MarkupForm, 它不同于创建 VirtualBox , 主要是因为组件收到道具 创建VirtualBox收到的道具是最简单的组件道具 创建控制程序接收
ISchemaVirtualFieldComponentProps
签署
createControllerBox<Props>(
name:string,
component:React.JSXElementConstructor<ISchemaVirtualFieldComponentProps>
) : React.FC<Props>
使用量
import React from 'react'
import {
SchemaMarkupForm as SchemaForm,
SchemaMarkupField as Field,
createControllerBox
} from '@formily/react-schema-renderer'
import { Card } from 'antd'
const FormCard = createControllerBox('card', ({ schema, children }) => {
return <Card {...schema.getExtendsComponentProps()}>{children}</Card>
})
export default () => (
<SchemaForm>
<FormCard title="This is card">
<Field name="aaa" type="string" />
</FormCard>
</SchemaForm>
)
获取注册
获得登记册,通过登记册注册的所有组件FormXXX API都在登记册中管理
签署
getRegistry(): ISchemaFormRegistry
清理注册
清除登记册并清除通过登记册注册的所有组件FormXXX API
签署
cleanRegistry(): void
类
整个类完全继承了@formily/core,例如FormPath和FormLifeCyle. 以下仅列出@formaly/react-schema-render的特有类别.
新 Schema( json : ISchema)
Schema解析引擎,由于一个数据满足了JSON Schema, 我们将将其解析成相应的 Schema 实例, 我们可以用一些工具方法快速处理一些事情。 同时,Schema Class提供了统一的协议差异平滑能力,以确保协议升级时的无缝和平滑升级
属性
| 属性名称 | 说明 | 类型 |
|---|---|---|
| 标题 | 字段标题 | React.ReactNode |
| 名称 | 字段的父属性名称 | string |
| 说明 | 实地说明 | React.ReactNode |
| 默认 | 字段默认 | any |
| 仅读 | 是否只读和可编辑 | boolean |
| 类型 | 字段类型 | ‘弦'("弦") |
| 语句 | 假设数据 | `箭头<弦' |
| 针头 | 检查字段值是否等于 Const 值 | any |
| 倍数 | 检查字段值是否可以被多值分割 | number |
| 上限 | 检查最大值( 大于) | number |
| 专有马克西姆 | 检查最大值( 大于或等于) | number |
| 最低 | 检查最小值( 小于) | number |
| 最小 | 最小值(小于或等于) | number |
| 最大长度 | 检查最大长度 | number |
| 分钟 | 检查最小长度 | number |
| 模式 | 常规检查规则 | 弦声 |
| 最大项目 | 最多条目数 | number |
| 分钟项目 | 最小条目数 | number |
| 唯一项目 | 是否检查重复 | boolean |
| 最大收益 | 最大属性数 | number |
| 收益 | 最小属性数 | number |
| 所需经费 | 需求 | boolean |
| 格式 | 正则类型 | InternalFormats |
| 属性 | 对象属性 | {[key : string]:Schema} |
| 项目 | 阵列描述 | `计划' |
| 额外 项目 | 其他数组元素描述 | Schema |
| 特性 | 动态匹配对象属性的图谋 | {[key : string]:Schema} |
| 额外收益 | 匹配对象外加属性的外加图 | Schema |
| 可编辑 | 字段是否可以编辑 | boolean |
| 可见 | 数据和样式是否可见 | boolean |
| 显示 | 样式是否可见 | boolean |
| x- 道具 | 字段扩展属性 | { [name: string]: any } |
| x 指数 | 外地订单 | number |
| x 规则 | 实地检查规则 | ValidatePatternRules |
| x 组件 | 外地用户界面组件 | string |
| x- 组件道具 | 字段 UI 组件属性 | {} |
| x- 放弃 | 字段扩展渲染函数 | <T = ISchemaFieldComponentProps>(props: T & { renderComponent: () => React.ReactElement}) => React.ReactElement |
| x 效应 | 外地副作用触发器 | (dispatch: (type: string, payload: any) => void,option?:object) => { [key: string]: any } |
方法
get
根据数据路径获取 Schema 儿童节点
签署
get(path?: FormPathPattern): Schema
使用量
const schema = new Schema({
type: 'object',
properties: {
array: {
type: 'array',
items: {
type: 'object',
properties: {
input: {
type: 'string'
}
}
}
}
}
})
schema.get('array[0].input') //{type:"string"}
merge
合并Schema
签署
merge(spec:ISchema): Schema
使用量
const schema = new Schema({
type: 'object',
properties: {
array: {
type: 'array',
items: {
type: 'object',
properties: {
input: {
type: 'string'
}
}
}
}
}
})
schema.merge({
title: 'root object'
})
/**
{
type:"object",
title:"root object",
properties:{
array:{
type:'array',
items:{
type:'object',
properties:{
input:{
type:'string'
}
}
}
}
}
}
**/
getEmptyValue
根据 Schema 类型获取当前 Schema 的无效值
签署
getEmptyValue() : '' | [] | {} | 0
使用量
const schema = new Schema({
type: 'object',
properties: {
array: {
type: 'array',
items: {
type: 'object',
properties: {
input: {
type: 'string'
}
}
}
}
}
})
schema.get('array.0.input').getEmptyValue() // ''
schema.get('array.0').getEmptyValue() // {}
schema.get('array').getEmptyValue() // []
schema.getEmptyValue() // {}
getSelfProps
获取不嵌入的 Schema 属性( 不包括像属性/ 项这样的嵌入属性)
签署
getSelfProps() : ISchema
使用量
const schema = new Schema({
type: 'object',
properties: {
array: {
type: 'array',
items: {
type: 'object',
properties: {
input: {
type: 'string'
}
}
}
}
}
})
schema.getSelfProps() // { type:"object" }
getExtendsRules
获取扩展检查规则。 这种方法比较复杂. 它会解析当前Schema的所有检查类型的属性和x规则属性,并最后将它们合并为一个统一的规则结构.
签署
getExtendsRules() : ValidateArrayRules
使用量
const schema = new Schema({
type:"string",
required:true,
maxLength:10
"x-rules":{
pattern:/^\d+$/
}
})
schema.getExtendsRules() // [{required:true},{max:10},{pattern:/^\d+$/}]
getExtendsRequired
获取是否需要它实际上是读取 Schema 所需的属性. 为什么它被封装在一个方法中,以确保用户不知道协议的升级? 我们只需要确保方法的后向相容性.
签署
getExtendsRequired(): void | boolean
使用量
const schema = new Schema({
type:"string",
required:true,
maxLength:10
"x-rules":{
pattern:/^\d+$/
}
})
schema.getExtendsRequired() // true
getExtendsEditable
获取 Schema 的可编辑状态, 与 GetExtends Ediable 能力一致, 也可以平滑协议差异
签署
getExtendsEditable() : void | boolean
使用量
const schema1 = new Schema({
type: 'string',
editable: false
})
schema1.getExtendsEditable() // false
const schema2 = new Schema({
type: 'string',
readOnly: true
})
schema2.getExtendsEditable() // false
const schema3 = new Schema({
type: 'string',
'x-props': {
editable: false
}
})
schema3.getExtendsEditable() // false
const schema4 = new Schema({
type: 'string',
'x-component-props': {
editable: false
}
})
schema4.getExtendsEditable() // false
getExtendsVisible
获取数据和样式可见属性
页:1
getExtendsVisible(): boolean
getExtendsDisplay
获取样式可见属性
页:1
getExtendsDisplay() : boolean
getExtendsTriggerType
获取触发Type,它与GetExtendsTriggerType能力一致,并且能够提供协议差异.
签署
getExtendsTriggerType() : 'onBlur' | 'onChange' | string
使用量
const schema1 = new Schema({
type: 'string',
'x-props': {
triggerType: 'onBlur'
}
})
schema1.getExtendsTriggerType() // onBlur
const schema2 = new Schema({
type: 'string',
'x-component-props': {
triggerType: 'onBlur'
}
})
schema2.getExtendsTriggerType() // onBlur
const schema3 = new Schema({
type: 'string',
'x-item-props': {
triggerType: 'onBlur'
}
})
schema3.getExtendsTriggerType() // onBlur
getExtendsProps
获取 x- props 属性
签署
getExtendsProps() : {}
getExtendsComponent
获取 x- props 属性
签署
getExtendsComponent() : string
getExtendsComponentProps
获取 X 组件- 道具属性, 这是 X 组件的组件属性
签署
getExtendsComponentProps() : {}
getExtendsRenderer
获取 x- 递归属性
签署
getExtendsRenderer() : <T = ISchemaFieldComponentProps>(
props: T & {
renderComponent: () => React.ReactElement
}
) => React.ReactElement
getExtendsEffect
获取 x 效果属性
签署
getExtendsEffect() : (
dispatch: (type: string, payload: any) => void,
option?: object
) => { [key: string]: any }
setProperty
设置当前方案的性质
签署
setProperty(key: string, schema: ISchema): Schema
setProperties
设置当前 Schema 批次的属性
签署
setProperties(properties: {[key : string]:ISchema}) : {[key : string]:Schema}
setArrayItems
将项目属性设定为当前方案
签署
setArrayItems(schema:Ischema) : Schema
getOrderProperties
按 x 索引顺序给出所有属性
签署
getOrderProperties() : {schema:Schema,key:string}[]
mapProperties
将图案的属性按顺序排列 (x-index)
签署
mapProperties(callback?: (schema: Schema, key: string) => any):any[]
toJSON
不输出依赖循环的json数据结构
签署
toJSON() : ISchema
fromJSON
根据 json 解析生成一个 Schema 对象
签署
fromJSON(json : ISchema) : Schema
isObject
确定当前方案是否为对象类型
签署
isObject() : boolean
isArray()
确定当前方案是否属于数组类型
签署
isArray() : boolean
构成部分
整个组件被完全继承了@formily/react,以下仅列出为@formily/react-schema-render的特有组件.
<SchemaForm/>
核心 JSON Schema 渲染组件
属性
interface ISchemaFormProps<
Value = any,
DefaultValue = any,
FormEffectPayload = any,
FormActions = ISchemaFormActions | ISchemaFormAsyncActions
> {
//Form value
value?: Value
//Form default value
defaultValue?: DefaultValue
//Form default value, weakly controlled
initialValues?: DefaultValue
//Form actions
actions?: FormActions
//Form effects
effects?: IFormEffect<FormEffectPayload, FormActions>
//Form instance
form?: IForm
//Form change callback
onChange?: (values: Value) => void
//Form submission callback
onSubmit?: (values: Value) => void | Promise<Value>
//Form reset callback
onReset?: () => void
//Form validation failure callback
onValidateFailed?: (valideted: IFormValidateResult) => void
//Form child node
children?: React.ReactElement
//Whether to open the dirty check
useDirty?: boolean
//Is it editable
editable?: boolean | ((name: string) => boolean)
//Whether to enable pessimistic verification, if the first verification fails, stop the remaining verification
validateFirst?: boolean
//Form Schema object
schema?: ISchema
//Instance level registration custom component
fields?: ISchemaFormRegistry['fields']
//Instance level registration virtual box component
virtualFields?: ISchemaFormRegistry['virtualFields']
//Instance level registration Form style component
formComponent?: ISchemaFormRegistry['formComponent']
//Instance level registration FormItem style component
formItemComponent?: ISchemaFormRegistry['formItemComponent']
}
<SchemaField/>
基于"数据路径",它自动地找到并使得Schema节点的内部组件,主要用于自定义组件内部执行递归渲染.
属性
interface ISchemaFieldProps {
//Data path
path?: FormPathPattern
}
<SchemaMarkupForm/>
让 SchemaForm 支持 jsx 标签标记的窗体组件, 需要与 Schema Markup Field 一起使用
属性
interface ISchemaFormProps<
Value = any,
DefaultValue = any,
FormEffectPayload = any,
FormActions = ISchemaFormActions | ISchemaFormAsyncActions
> {
//Form value
value?: Value
//Form default value
defaultValue?: DefaultValue
//Form default value, weakly controlled
initialValues?: DefaultValue
//Form actions
actions?: FormActions
//Form effects
effects?: IFormEffect<FormEffectPayload, FormActions>
//Form instance
form?: IForm
//Form change callback
onChange?: (values: Value) => void
//Form submission callback
onSubmit?: (values: Value) => void | Promise<Value>
//Form reset callback
onReset?: () => void
//Form validation failure callback
onValidateFailed?: (valideted: IFormValidateResult) => void
//Form child node
children?: React.ReactElement
//Whether to open the dirty check
useDirty?: boolean
//Is it editable
editable?: boolean | ((name: string) => boolean)
//Whether to enable pessimistic verification, if the first verification fails, stop the remaining verification
validateFirst?: boolean
//Form Schema object
schema?: ISchema
//Instance level registration custom component
fields?: ISchemaFormRegistry['fields']
//Instance level registration virtual box component
virtualFields?: ISchemaFormRegistry['virtualFields']
//Instance level registration Form style component
formComponent?: ISchemaFormRegistry['formComponent']
//Instance level registration FormItem style component
formItemComponent?: ISchemaFormRegistry['formItemComponent']
}
使用量
import {
SchemaMarkupForm as SchemaForm,
SchemaMarkupField as Field
} from '@formily/react-schema-renderer'
export default () => {
return (
<SchemaForm>
<Field name="aa" type="string" />
</SchemaForm>
)
}
<SchemaMarkupField/>
SchemaForm 支持 jsx 标签标记的 Field 部分, 需要与 Schema MarkupForm 一起使用
属性
type IMarkupSchemaFieldProps = ISchema
<InternalForm/>
核心形式与 @ formily/ react 中的形式组件相同
<InternalField/>
核心字段同"formily/react"中的"字段"组件一样,主要用于复杂的自定义组件.
接口
继承 @formily/ react and @formily/core's Interfaces 作为一个整体,下文仅列出 @formily/react-schema-render.
连接选项
注册组件的连接参数
interface IConnectOptions {
valueName?: string //value name
eventName?: string //get value callback name
defaultProps?: {} //component default props
getValueFromEvent?: (event?: any, value?: any) => any //get value from event callback.
getProps?: (
//props transformer
componentProps: {},
fieldProps: MergedFieldComponentProps
) => {} | void
getComponent?: (
//component transformer
Target: any,
componentProps: {},
fieldProps: MergedFieldComponentProps
) => React.JSXElementConstructor<any>
}
ISchema 外地组件技术
必须自定义组件收到的属性。 只要它涉及到开发自定义组件,就需要理解协议.
interface ISchemaFieldComponentProps {
//State name, FieldState
displayName?: string
//Data path
name: string
//Node path
path: string
//Whether it has been initialized
initialized: boolean
//Whether it is in the original state, the state is true only when value===intialValues
pristine: boolean
//Whether it is in a legal state, as long as the error length is greater than 0, the valid is false.
valid: boolean
//Whether it is in an illegal state, as long as the error length is greater than 0, the valid is true.
invalid: boolean
//Is it in check state?
validating: boolean
//Whether it is modified, if the value changes, the property is true and will be true for the entire lifetime of the field.
modified: boolean
//Whether it is touched
touched: boolean
//Whether it is activated, it will be triggered to true when the field triggers the onFocus event, and false when onBlur is triggered.
active: boolean
//Whether it has been accessed, when the field triggers the onBlur event, it will be triggered to true
visited: boolean
//Is it visible, note: if the status is false, the value of the field will not be submitted, and the UI will not display
visible: boolean
//Whether to show, note: if the status is false, then the value of the field will be submitted, the UI will not display, similar to the form hidden field
display: boolean
//Is it editable
editable: boolean
//Whether it is in the loading state, note: if the field is in asynchronous check, loading is true
loading: boolean
//The field has multiple parameters. For example, when the field onChange is triggered, multi-parameter data is passed to the event callback, then the values of all parameters are stored here.
values: any[]
//Field error message
errors: string[]
//Field alert message
warnings: string[]
//Field value, which is constant equal to values[0]
value: any
//Initial value
initialValue: any
//Verification rules, specific type descriptions refer to the following documents
rules: ValidatePatternRules[]
//Required or not
required: boolean
//Has it been mounted?
mounted: boolean
//Has it been unmounted?
unmounted: boolean
//Field extension property, under the SchemaForm ISchema structure
props: ISchema
//The schema object of the current field
schema: Schema
//Current operation data set of the field
mutators: IMutators
//Form instance
form: IForm
//Recursive rendering function
renderField: (
addtionKey: string | number,
reactKey?: string | number
) => React.ReactElement
}
ISchema 虚拟外地组件方法
虚拟字段组件收到的属性,只要涉及虚拟字段的注册,就需要理解协议.
interface ISchemaVirtualFieldComponentProps {
//State name, VirtualFieldState
displayName: string
//Field data path
name: string
//Field node path
path: string
//Whether it has been initialized
initialized: boolean
//Is it visible, note: if the status is false, the UI will not be displayed, and the data will not be submitted (because it is a VirtualField)
visible: boolean
//Whether to show, note: if the state is false, the UI will not be displayed, and the data will not be submitted (because it is a VirtualField)
display: boolean
//Has it been mounted?
mounted: boolean
//Has it been unmounted?
unmounted: boolean
//Field extension attribute
props: ISchema
//The schema object of the current field
schema: Schema
//Form instance
form: IForm
//Child element
children: React.ReactElement[]
//Recursive rendering function
renderField: (
addtionKey: string | number,
reactKey?: string | number
) => React.ReactElement
}
ISchemaForm Registry (英语)
无论是普通字段、虚拟字段,还是表格/表格项目,都将在此注册.
interface ISchemaFormRegistry {
fields: {
[key: string]: React.JSXElementConstructor<ISchemaFieldComponentProps>
}
virtualFields: {
[key: string]: React.JSXElementConstructor<
ISchemaVirtualFieldComponentProps
>
}
formItemComponent: React.JSXElementConstructor<ISchemaFieldComponentProps>
formComponent: string | React.JSXElementConstructor<any>
}
ISchema 计划
Schema协议对象,主要用于制约json结构以满足Schema协议
interface ISchema {
/** base json schema spec**/
title?: React.ReactNode
description?: React.ReactNode
default?: any
readOnly?: boolean
writeOnly?: boolean
type?: 'string' | 'object' | 'array' | 'number' | string
enum?: Array<string | number | { label: React.ReactNode; value: any }>
const?: any
multipleOf?: number
maximum?: number
exclusiveMaximum?: number
minimum?: number
exclusiveMinimum?: number
maxLength?: number
minLength?: number
pattern?: string | RegExp
maxItems?: number
minItems?: number
uniqueItems?: boolean
maxProperties?: number
minProperties?: number
required?: string[] | boolean
format?: string
/** nested json schema spec **/
properties?: {
[key: string]: ISchema
}
items?: ISchema | ISchema[]
additionalItems?: ISchema
patternProperties?: {
[key: string]: ISchema
}
additionalProperties?: ISchema
/** extend json schema specs */
visible?: boolean //Field initial visible status(Whether the data is visible)
display?: boolean //Field initial display status(Whether the style is visible)
editable?: boolean
['x-props']?: { [name: string]: any }
['x-index']?: number
['x-rules']?: ValidatePatternRules
['x-linkages']?: Array<{
target: FormPathPattern
type: string
[key: string]: any
}>
['x-mega-props']?: { [name: string]: any }
['x-component']?: string
['x-component-props']?: { [name: string]: any }
['x-render']?: <T = ISchemaFieldComponentProps>(
props: T & {
renderComponent: () => React.ReactElement
}
) => React.ReactElement
['x-effect']?: (
dispatch: (type: string, payload: any) => void,
option?: object
) => { [key: string]: any }
}
ISchema 行动
核心动作继承了 @ formily/ react's IFMActions, 主要添加了 getSchema API
interface ISchemaFormActions extends IFormActions {
getSchema(): Schema
getFormSchema(): Schema
}
ISchemaForm合成行动
核心动作继承了 @ formily/ react's IFormAsync Actions, 主要添加了 getSchema API
interface ISchemaFormAsyncActions extends IFormAsyncActions {
getSchema(): Promise<Schema>
getFormSchema(): Promise<Schema>
}
IFORMValidate Result (英语)
校准结果
interface IFormValidateResult {
errors: Array<{
path: string
messages: string[]
}>
warnings: Array<{
path: string
messages: string[]
}>
}
内部格式
内置格式校验和
type InternalFormats =
| 'url'
| 'email'
| 'ipv6'
| 'ipv4'
| 'idcard'
| 'taodomain'
| 'qq'
| 'phone'
| 'money'
| 'zh'
| 'date'
| 'zip'
| string
验证
原始检查说明
interface ValidateDescription {
// built-in rules,ref: string rules
format?: InternalFormats
// custom validation
validator?: CustomValidator
// required
required?: boolean
// pattern
pattern?: RegExp | string
// max length
max?: number
// maximum
maximum?: number
// exclusiveMaximum
exclusiveMaximum?: number
// exclusiveMinimum
exclusiveMinimum?: number
// minimum
minimum?: number
// min
min?: number
// length
len?: number
// whitespace
whitespace?: boolean
// enum
enum?: any[]
// error message
message?: string
[key: string]: any
}
验证响应
type SyncValidateResponse =
| null
| string
| boolean
| {
type?: 'error' | 'warning'
message: string
}
type AsyncValidateResponse = Promise<SyncValidateResponse>
type ValidateResponse = SyncValidateResponse | AsyncValidateResponse
自定义变量
自定义检查功能
type CustomValidator = (
value: any,
description?: ValidateDescription
) => ValidateResponse
验证辅助规则
核查规则集
type ValidatePatternRules =
| InternalFormats
| CustomValidator
| ValidateDescription
| Array<InternalFormats | CustomValidator | ValidateDescription>