Form component
npm install @uiw/react-formForm 表单
===




由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据。
``jsx`
import { Form, FormItem } from 'uiw';
// or
import { Form, FormItem } from '@uiw/react-form';
`jsx mdx:preview&bg=#fff
import React, { useState, useRef } from "react";
import { Form, Input, Row, Col, Slider, Button, Notify } from 'uiw';
export default function Demo() {
const form = useRef()
const onSubmit = () => {
form.current.onSubmit()
}
const resetForm = () => {
form.current.resetForm()
}
const getFieldValues = () => {
console.log('getFieldValues', form.current.getFieldValues())
}
const setFieldValue=()=>{
form.current.setFieldValue('name','UIW')
}
return (
,
});
} else {
Notify.success({
title: '提交成功!',
description: 姓名为:${current.name},提交完成,将自动填充初始化值!,
});
}
}}
fields={{
name: {
label: '姓名',
children:
},
}}
>
{({ fields, state, canSubmit }) => {
return (
{fields.name}
|
|
{JSON.stringify(state.current)}
|
)
}}
$3
一般校验可不需引入外部包解决,如果遇到大型工程表单比较多的地方推荐使用 jquense/yup
`jsx mdx:preview&bg=#fff
import React from 'react';
import { Form, Input, Notify, Checkbox, Switch, RadioGroup, Radio, Textarea, Row, Col, Button, Select, SearchSelect } from 'uiw';export default function Demo() {
return(
onSubmit={({initial, current}) => {
const errorObj = {};
if (current.userName.startsWith('u')) {
errorObj.userName = 姓名 ${current.userName} 不能以 ‘u’ 开头;
}
if (!current.checkboxOne) {
errorObj.checkboxOne = '一个多选条件 为必填';
}
if (!current.terms) {
errorObj.terms = '必须统一服务条款';
}
if(Object.keys(errorObj).length > 0) {
const err = new Error();
err.filed = errorObj;
throw err;
}
Notify.success({
title: '提交成功!',
description: 姓名为:${current.userName},提交完成,将自动填充初始化值!,
});
}}
onSubmitError={(error) => {
if (error.filed) {
return { ...error.filed };
}
return null;
}}
fields={{
userName: {
initialValue: 'uiw',
label: '姓名',
children: ,
help: '以“u”开头的名字将在此处显示错误信息'
},
age: {
initialValue: '9',
label: '年龄',
children:
},
select: {
children: (
)
},
searchSelect: {
initialValue:[{label: 'a7', value: 7},{label: 'a8', value: 8}],
children: (
allowClear
labelInValue={true}
showSearch={true}
mode="multiple"
disabled={false}
placeholder="请选择选项"
option={[
{ label: 'a1', value: 1 },
{ label: 'a2', value: 2 },
{ label: 'a3', value: 3 },
{ label: 'a4', value: 4 },
{ label: 'a5', value: 5 },
{ label: 'a6', value: 6 },
{ label: 'a7', value: 7 },
{ label: 'a8', value: 8 },
]}
/>
)
},
checkbox: {
initialValue: ['四川菜'],
label: '选择你想吃的菜',
children: (
菜系
四川菜
湖北菜
西北菜
新疆菜
东北菜
家常菜
红烧武昌鱼
麻婆豆腐
北京烤鸭
)
},
checkboxOne: {
inline: true,
label: '一个多选条件',
children: 四川菜
},
switch: {
inline: true,
initialValue: true,
label: '开启',
children:
},
radioGroup: {
inline: true,
initialValue: '男',
label: '单选',
children: (
男
女
人妖
未知
)
},
textarea: {
initialValue: '',
label: '多行文本输入框',
children:
},
terms: {
validator: (currentValue) => {
return !currentValue ? '必须统一服务条款' : null;
},
style: { marginBottom: 0 },
children: 已阅读并同意服务条款
}
}}
>
{({ fields, state, canSubmit, resetForm }) => {
console.log('fields:-->', state);
return (
{fields.userName}
{fields.age}
|
{fields.select}
{fields.searchSelect}
|
{fields.checkbox}
{fields.checkboxOne}
|
{fields.radioGroup}
|
{fields.switch}
|
{fields.textarea}
|
{fields.terms}
|
|
{JSON.stringify(state.current, null, 2)}
|
)
}}
)
}
`$3
`jsx mdx:preview&bg=#fff
import React from 'react';
import { Form, Input, Row, Col, Notify, Button } from 'uiw';export default function Demo() {
return (
onSubmit={({initial, current}) => {
const errorObj = {};
if (!current.username) {
errorObj.username = '用户名不能为空!';
}
if (!current.password) {
errorObj.password = '密码不能为空!';
}
if(Object.keys(errorObj).length > 0) {
const err = new Error();
err.filed = errorObj;
Notify.error({ title: '提交失败!', description: '请确认提交表单是否正确!' });
throw err;
}
console.log('-->>', initial, current);
Notify.success({ title: '提交成功!', description: '恭喜你登录成功!' });
}}
onSubmitError={(error) => {
if (error.filed) {
return { ...error.filed };
}
return null;
}}
fields={{
username: {
labelClassName: 'fieldLabel',
labelFor: 'username-inline',
children:
},
password: {
labelClassName: 'fieldLabel',
labelFor: 'password-inline',
children:
},
}}
>
{({ fields, state, canSubmit, resetForm }) => {
console.log('fields:', state);
return (
{fields.username}
{fields.password}
|
|
)
}}
);
}
`登录
`jsx mdx:preview&bg=#fff
import React from 'react';
import { Form, Input, Row, Col, Checkbox, Notify, Button } from 'uiw';export default function Demo() {
return (
onSubmit={({initial, current}) => {
console.log('-->>', initial, current);
}}
fields={{
username: {
labelClassName: 'fieldLabel',
labelStyle: { width: 60 },
labelFor: 'username',
children:
},
password: {
labelClassName: 'fieldLabel',
labelStyle: { width: 60 },
labelFor: 'password',
children:
},
terms: {
validator: (currentValue) => !currentValue ? '必须统一服务条款' : null,
children: 已阅读并同意
}
}}
>
{({ fields, state, canSubmit }) => {
console.log('fields:', state);
return (
)
}}
)
}
`$3
`jsx mdx:preview&bg=#fff
import React from 'react';
import { Form, Input, Select, Row, Col, Button } from 'uiw';export default function Demo() {
return (
onSubmit={({initial, current}) => {
console.log('-->>', initial, current);
}}
fields={{
firstName: {
labelClassName: 'fieldLabel',
labelStyle: { width: 60 },
inline: true,
label: '姓氏',
children:
},
lastName: {
labelClassName: 'fieldLabel',
labelStyle: { width: 60 },
initialValue: '先生',
inline: true,
label: '名字',
children:
},
email: {
labelClassName: 'fieldLabel',
labelStyle: { width: 60 },
validator: (currentValue) => {
return currentValue && currentValue.length < 2 ? 'Password must be 8+ characters' : null;
},
inline: true,
label: 'Email',
children:
},
select: {
labelClassName: 'fieldLabel',
labelStyle: { width: 60 },
inline: true,
label: '选择器',
children: (
),
},
}}
>
{({ fields, state, canSubmit }) => {
console.log('fields:', state);
return (
{fields.firstName}
{fields.lastName}
|
{fields.email}
{fields.select}
|
|
)
}}
)
}
`$3
表单组件中,应用自定义 控件组件。> ⚠️ 注意,自定义控件需要两个必要的
props 参数,value 和 onChange
-
value 用于值传递,
- onChange(value) 用于值变更需要执行的回调函数,回调函数第一个参数必须是 value。`jsx mdx:preview&bg=#fff
import React from 'react';
import { Form, Row, Col, Dropdown, Menu, Icon, Button, Notify } from 'uiw';// 自定义组件
function CustomSelect(props) {
const { option = [], onChange } = props;
const [value, setValue] = React.useState(props.value);
const [isOpen, setIsOpen] = React.useState(false);
React.useEffect(() => {
if (value !== props.value) {
setValue(props.value);
}
}, [props.value]);
const label = option.find(item => value === item.value);
return (
trigger="click"
onVisibleChange={(open) => setIsOpen(open)}
isOpen={isOpen}
menu={
}
>
style={{
boxShadow: 'inset 0 0 0 1px rgba(16, 22, 26, 0.2), inset 0 -1px 0 rgba(16, 22, 26, 0.1)'
}}
type="link"
>
{label.label}
);
}// 自定义组件应用实例
export default function Demo() {
return (
onSubmitError={(error) => {
if (error.filed) {
return { ...error.filed };
}
return null;
}}
onSubmit={({initial, current}) => {
console.log('~~~', current);
const errorObj = {};
if (!current.select) {
errorObj.select = '内容为空,请输入内容';
}
if(Object.keys(errorObj).length > 0) {
const err = new Error();
err.filed = errorObj;
Notify.error({ title: '提交失败!', description: '请确认提交表单是否正确!' });
throw err;
}
Notify.success({
title: '提交成功!',
description: 表单提交成功,内容为:${current.select},将自动填充初始化值!,
});
}}
fields={{
select: {
initialValue: 0,
children: (
{ label: '请选择', value: 0 },
{ label: '经济舱', value: 1 },
{ label: '豪华经济舱', value: 2 },
{ label: '商务舱', value: 3 },
{ label: '头等舱', value: 4 },
]} />
)
},
}}
>
{({ fields, state, canSubmit }) => {
return (
{fields.select}
|
|
)
}}
)
}
`$3
对组件
FormItem 竖排展示示例。> ⚠️ 注意:
FormItem 组件只在 Form 组件中使用,在 @v4.10.4+ 以上版本可以当普通 form 使用。
`jsx mdx:preview&bg=#fff
import React from 'react';
import { Form, FormItem, Button, Input } from 'uiw';export default function Demo() {
const [formData, setFormData] = React.useState({});
const handleSubmit = (_, e) => {
e && e.preventDefault();
const fData = new FormData(e.target);
const data = {};
fData.forEach((value, key) => { data[key] = value; });
setFormData(data);
}
return (
);
}
`$3
对组件
FormItem 横排展示示例。> ⚠️ 注意:
FormItem 组件只在 Form 组件中使用,在 @v4.10.4+ 以上版本可以当普通 form 使用。
`jsx mdx:preview&bg=#fff
import React from 'react';
import { Form, FormItem, Input } from 'uiw';export default function Demo() {
return (
)
}
`Form
| 参数 | 说明 | 类型 | 默认值 |
|--------- |-------- |--------- |-------- |
| fields | 设置字段 | object | - |
| children | 回调 {
fields, state, canSubmit, resetForm} | function | - |
| onSubmit | 提交表单时调用 | (state: FormSubmitProps, event: React.FormEvent) => any | - |
| afterSubmit @3.0.0+ | 提交回调 {initial, current} | function({ initial, current }) | - |
| onChange | 表单发生改变回调函数 {initial, current} | function({ initial, current }) | - |
| onSubmitError | 调用 onSubmit 抛出的任何错误。从字段名称返回对象映射。 | function | - |
| resetOnSubmit | 在 onSubmit 成功后将表单重置为其初始状态。| bool | true |
| ref | 返回form各种内部函数,可用于主动触发事件 | Ref | - |
#### fields
`js
{
firstName: {
initialValue: '王',
inline: true,
label: '姓',
labelClassName: 'fieldLabel',
labelStyle: { width: 60 },
// 验证,通过 canSubmit() 方法获得,提交按钮是否被禁用
validator: (currentValue) => {},
help: '帮助提示信息!',
children:
},
}
`#### ref
`jsx
const form = useRef()
render(``js
form.current.onSubmit() // 提交表单
form.current.resetForm() // 重置form
const fieldValues = form.current.getFieldValues() // 获取所有 field的 value对象
const error = form.current.getError() // 获取所有提交时验证错误
form.current.setFields({ / [fieldName]: value / }) // 设置表单的值,覆盖 form所有 field的值
form.current.setFieldValue(fieldName, value) // 对单个 field设置 value,如果 value为数组请自行深度拷贝后传值,以免破坏原数组
``| 参数 | 说明 | 类型 | 默认值 |
|--------- |-------- |--------- |-------- |
| label | 表单标题展示 | string | - |
| required | 表单是否必填标识 | boolean | - |
| labelClassName | 表单标题样式名称 | string | - |
| labelStyle | 表单标题样式 | object | - |
| labelFor | 列的宽度相对于同一网格中其他列的比率 | number | - |
| help | 提示信息 | ReactNode | - |
| hasError | 如果为true,则应用错误CSS。转动边框并帮助文字变红。 | number | - |