1、下载
npm i form-render --save
FormRender依赖ant design,单独使用不要忘记同时安装antd
2、使用
(1)配置schema条件
const schema = {
除了rules和default,都支持双大括号语法"{{函数表达式}}",如title:"{{formData.x.y === 'us' ? '美元':'人民币'}}"
函数表达式可使用以下2关键字:
formData:整个form的值,当两个关联组件距离较远时,可以从顶层的formData里获取
rootValue:父组件的值上一级的值,一般在列表场景中的子元素获取对应index的item时使用
const schema = {
type: 'object',
properties: {
select1: {
title: '单选',
description: '尝试选择“显示输入框”',
type: 'string',
enum: ['a', 'b'],
enumNames: ['隐藏输入框', '显示输入框'],
disabled: '{{rootValue.input1.length > 5}}',
default: 'a',
},
input1: {
title: '输入框',
description: '尝试输入超过5个字符',
type: 'string',
hidden: '{{formData.select1 == "a"}}',
},
},
};
type: 'object', 描述里组件的值的类型,用于校验数据类型,也用于判断使用哪个组件来渲染,以及校验表单数据。
'string', 'number', 'boolean', 'array', 'object', 'range', 'html'
items:{} 只在数组(type:array)中使用,items用于包裹数组的子熟悉,目前只支持是对象
properties: { 只在对象组件(type: object)中使用,properties用于包裹对象的子属性
input1: { 描述当前组件的名称,和实际生成的组件无关
title: '名称', 组件默认在上方显示的名称
description:"在名称旁边提示的文字信息",
extra:"string|html字符串", 用于展示信息,在元素下方提示
default:当前组件的默认值,
placeholder:"当前组件的提示值", 注意placeholder的值遵循底层对应组件所需要的值的书写规范
bind:string | string[] | false, 当从服务器请求得来的属性名和组件展示的字段名不同时,指明表单的某个字段对应的是外部数据的另一个字段
如:form.setValues({'key','value'})
bind:'key', 将value值绑定到input上
bind:['key1',"key2"], 如时间选择器中,绑定起始时间值和截至时间值
enum: ["hz", "wh", "gy"], 框的value值
enumNames: ["杭州", "武汉", "贵阳"] 框右边的文字
单选对应type:'string'多选对应type:"array"
min:最小值或最小长度,
max:最大值或最大长度,
required: true, 是否必填
readOnly:true, 组件是只读,true的情况,FormRender默认使用html组件渲染。
hidden:true|false, 是否隐藏当前组件
disabled: true, 是否禁用当前组件
displayType: 'row'|"column"|"inline", label和组件排列方向
labelWidth: 130, 标题文字大小
width:'20px', 单个元素的展示宽度(带label一起),支持px和%
labelWidth:110, label宽度,数字值单位为px,也可使用'20%'/'2rem'等
className:"", 指明单个表单元素的className,方便自定义样式
type: 'string', 当前组件的值的类型
wiget:"select", 指定使用哪个组件来渲染,是优先级最高的一个字段,用于明确指定使用某个“内置组件”或“自定义组件”。
具体看官网的内置组件
readOnlyWidget:"自定义控件", 指明在只读模式使用自定义控件来渲染
format:"url", 默认格式验证规则,且辅助type一同用于判断使用哪个组件来渲染,以及校验表单数据
'image', 'textarea', 'color', 'email', 'url', 'dateTime', 'date', 'time', 'upload'
rules:[ 自定义验证提示规则
{
pattern: "^[A-Za-z0-9]+$", 正则匹配
message: "未匹配时的错误提示"
len:8, 长度限制
},{
zi
可以设置多个匹配规则...
}
],
validator: (rule, value) => value === 'muji', 自定义校验规则
props:{ antd中对应组件可传递的prop
},
},
select1: {
title: '单选',
type: 'string',
enum: ['a', 'b', 'c'],
enumNames: ['早', '中', '晚'],
},
},
};
1.0补充说明
type,format,enum和widget字段决定了使用哪个组件来渲染。具体判断规则见内置组件
type,format,min,max,required和rules字段用于做校验判断
props字段用于补充组件支持的更为细致的属性
1.1修改默认提示模板
validateMessages
可以通过配置validateMessages属性,修改对应的提示模板,一种常见的使用方式,是配置国际化提示信息:
const validateMessages = {
required: '${title}是必选字段', 目前可以用的转义字段为${title}/${min}/${max}/${len}/${pattern}
...
};
<Form validateMessages={validateMessages} />;
1.2多个表单之间的联动
使用formData或rootValue
(1)properties属性不需要.出来
(2)输入框、单|多选按钮|框、下拉框等,都是直接.出对应的配置属性名称即可获取到值,如:
const schema = {
type: 'object',
properties: {
input: {
title: '{{formData.config.title || "输入框"}}',
type: 'string',
placeholder: '{{formData.config.placeholder}}',
props: {
size: '{{formData.config.size}}',
},
hidden: '{{formData.config.hidden === true}}',
readOnly: '{{formData.config.readOnly === true}}',
disabled: '{{formData.config.disabled === true}}',
},
rate: {
title: 'rate',
type: 'number',
widget: 'rate',
},
config: {
title: '配置',
type: 'object',
placeholder: 'aa',
properties: {
title: {
title: 'title',
type: 'string',
},
placeholder: {
title: '{{formData.config.config2.child}}',
type: 'string',
},
size: {
title: 'input大小',
type: 'string',
enum: ['large', 'middle', 'small'],
enumNames: ['大', '中', '小'],
widget: 'radio',
},
hidden: {
title: '是否隐藏',
type: 'boolean',
},
readOnly: {
title: '是否只读',
type: 'boolean',
},
disabled: {
title: '是否置灰',
type: 'boolean',
},
config2: {
title: '嵌套配置',
type: 'object',
properties: {
child: {
titile: '嵌套input',
type: 'string',
},
},
},
},
},
},
};
1.2.5表单方法
1.生命周期
<FormRender form={form} schema={schema} onMount={onMount} />
(1)onMount
在表单首次加载时执行
表单首次加载的定义是:当非空的schema首次传入FormRender完成表单渲染之后,其中undefined、null、{}都视为“空”的 schema。
常用于加载初始数据,或是根据服务端接口获取数据进一步补充schema(例如下拉选框的选项)
如果schema来自服务端接口,注意不要使用onMount来加载schema,而使用componentDidMount,因为onMount的触发机制是判断非空 schema 已经传入 FormRender
(2)beforeFinish
用户调用form.submit提交开始
const beforeFinish = ({ data, errors, schema, ...rest }) => {
若校验未通过,则需要返回如下格式的内容,传递给onFinish第二个参数
return { name: 'select1', error: ['外部校验错误'] };
};
(3)onFinish
在beforeFinish之后执行
const onFinish = (data, errors) => {
if (errors.length > 0) {
message.error(
'校验未通过:' + JSON.stringify(errors.map(item => item.name))
);
} else {
fakeApi('xxx/submit', data).then(_ => message.success('提交成功!'));
}
2.Form组件属性
<Form
schema
form
onFinish
beforeFinish
onMount
widgets
watch
validateMessages 修改默认的校验提示信息。
removeHiddenData=boolean 提交数据的时候是否去掉已经被隐藏的元素的数据,默认不隐藏
debug 开启debug模式,时时显示表单内部状态,开发的时候强烈建议打开
displayType="" 表单元素与label同行or分两行展示,inline则整个展示自然顺排
readOnly 整个表单只读
column:1 一行展示多少列
mapping:{} schema与组件的映射关系表,当内置的表不满足时使用,可以理解为如何解析type,详见官网https://x-render.gitee.io/form-render/schema/inner-widget
disabled=boolean 全部表单元素禁用
debugCss=boolean 用于css问题的调整,显示css布局提示线
locale 展示语言,目前只支持中文、英文 string('cn'/'en')
configProvider={} antd的configProvider,配置透传
allCollapsed=boolean 对象组件是否默认折叠
debounceInput=boolean 是否开启输入时使用快照模式,仅建议在表单巨大且表达式非常多时开启
></Form>
回调方法
(1)form.setValues({ input1: 'hello world', select1: 'c','child.childCustom':'xx' }); 设置对应组件的值或添加新内容,新内容可供bind使用
(2)form.setSchemaByPath('child.childCustom',{rquired:true,default:"默认值"}); 设置对应组件的schema字段
或通过回调函数的方式,可以取得配置项的结果
form.setSchemaByPath('child.childCustom',({type})=>{..., return {type:"number"})}
(3)submit 触发提交流程,一般在提交按钮上使用
form.submit()
(4)resetFields 清空表单(也会清空一些内置状态,例如校验)
form.resetFields()
(5)errorFields 表单校验错误的数组 array,[{name, error: []}]
form.errorFields 当错误被提交后(如:beforeFinish中返回的错误),返回校验错误的数组
(6)setErrorFields 外部手动修改errorFields校验信息,用于外部校验回填
form.setErrorFields([{name:'select1',error:['www']}]) 用于覆盖会添加errorFields中的内容
(7)setValues 外部手动修改 formData,用于已填写的表单的数据回填 (formData: any) => void
(8)setValueByPath 外部修改指定单个 field 的数据(原名 onItemChange) (path: string, value: any) => void
(9)setSchemaByPath 指定路径修改 schema (path: string, value: any) => void
(10)setSchema 指定多个路径修改 schema。注 1 ({ path1: value1, path2: value2 }) => void
(11)getValues 获取表单内部维护的数据
(12)schema 表单的schema
(13)touchedKeys 已经触碰过的field的数据路径
(14)removeErrorField 外部手动删除某一个path下所有的校验信息
(15)formData 表单内部维护的数据,建议使用getValues/setValues
{
type: "object",
properties: {
input1: {
title: "简单输入框",
type: "string",
required: true
},
select1: {
title: "单选",
type: "string",
enum: ["a", "b", "c"],
enumNames: ["早", "中", "晚"]
},
child: {
title: "嵌套",
type:"object",
properties: {
childCustom:{
type:"string",
title:"嵌套cutom",
}
}
}
}
}
1.2.5watch监听
(1)创建监听
const watch={
"#":(val)=>{
监听所有表单的变化和
},
'监听的组件路径,无需.properties':(vale)=>{
监听单个组件的值的变化
},
immediate:true 立即执行一次监听回调
}
(2)使用监听
1.3自定义组件
注册组件
<Form form={form} schema={schema} widgets={{ 注册名称: 引入的组件 }} />
使用组件
properties: {
custom: {
title: '自定义组件',
type: 'array', 必须指定type才能生效
widget: '注册名称',
readOnlyWidget:'只读组件注册名称',
props:{
传递给组件的属性,外层的schema等也会传递给组件
}
},
},
类组件:
import FormRender, { connectForm } from 'form-render';
class Demo extends React.Component {
render() {
const { form } = this.props;
return (
<div>
<FormRender form={form} schema={schema} />
<Button type="primary" onClick={form.submit}>
提交
</Button>
</div>
);
}
}
export default connectForm(Demo);
函数组件:
import FormRender, { useForm } from 'form-render';
const Demo = () => {
const form = useForm();
return (
<div>
<FormRender form={form} schema={schema} />
<Button type="primary" onClick={form.submit}>
提交
</Button>
</div>
);
};
export default Demo;