@formily/react-schema-renderer

中文文档
1.3.17发布于 2021/05/13MITTypeScriptCommonJS近 30 天下载 2494
中文使用文档
文档目录8 节
  1. 安装
  2. 目录
  3. 使用量
  4. 高级教程
  5. API 密码
  6. 类
  7. 构成部分
  8. 接口

@ formatily/ react-schema- relander (英语)

页:1 简体中文

Schema渲染引擎,软件包主要依靠@formily/resact,其责任非常简单,核心做两件事:

  • 分析窗体外观协议, 递归渲染
  • 管理自定义组件

安装

npm install --save @formily/react-schema-renderer

目录

使用量


快开始

如果您是直接基于 @ 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>

版本与发布记录

@formily/react-schema-renderer 共发布 68 个版本,首次发布于 2020/02/21;过去 12 个月发布了 0 个版本。

版本发布日期距今
1.3.17latest2021/05/135 年前
1.3.17-beta.02021/05/135 年前
1.3.162021/05/135 年前
1.3.152021/04/165 年前
1.3.142021/04/145 年前
1.3.132021/03/155 年前

关于 @formily/react-schema-renderer 的常见问题

@formily/react-schema-renderer 是什么?

页:1 简体中文

如何安装 @formily/react-schema-renderer?

在项目目录运行 npm install @formily/react-schema-renderer,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@types/react(^16.8.23)、react(>=16.8.0)、react-dom(>=16.8.0)、react-eva(^1.1.7)、rxjs(^6.5.1)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@formily/react-schema-renderer 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@formily/react-schema-renderer 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@formily/react-schema-renderer 可以商用吗?

@formily/react-schema-renderer 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@formily/react-schema-renderer 的下载量有多少?

根据 npm 官方下载统计,@formily/react-schema-renderer 在 2026/10/16 – 2026/11/14 这 30 天内被下载 2,494 次,日均约 83 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@formily/react-schema-renderer 还在维护吗?

最新版本 1.3.17 发布于 2021/05/13(5 年前);至今共发布 68 个版本,其中过去 12 个月发布了 0 个;首次发布于 2020/02/21。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。