博主最近在用antd Form組件開發表單功能,深深感慨antd Form組件功能也忒強大了,可是寫起來真的挺麻煩的,相信不少小夥伴在用antd Form組件的時候都有一樣的感覺吧。css
看一下antd官網的一個例子,須要Form.create包裝表單組件,而後表單每一項使用getFieldDecorator進行具體描述。node
import { Form, Input, Button, Checkbox } from 'antd';
const formItemLayout = {
labelCol: { span: 4 },
wrapperCol: { span: 8 },
};
const formTailLayout = {
labelCol: { span: 4 },
wrapperCol: { span: 8, offset: 4 },
};
class DynamicRule extends React.Component {
state = {
checkNick: false,
};
check = () => {
this.props.form.validateFields(err => {
if (!err) {
console.info('success');
}
});
};
handleChange = e => {
this.setState(
{
checkNick: e.target.checked,
},
() => {
this.props.form.validateFields(['nickname'], { force: true });
},
);
};
render() {
const { getFieldDecorator } = this.props.form;
return (
<div>
<Form.Item {...formItemLayout} label="Name">
{getFieldDecorator('username', {
rules: [
{
required: true,
message: 'Please input your name',
},
],
})(<Input placeholder="Please input your name" />)}
</Form.Item>
<Form.Item {...formItemLayout} label="Nickname">
{getFieldDecorator('nickname', {
rules: [
{
required: this.state.checkNick,
message: 'Please input your nickname',
},
],
})(<Input placeholder="Please input your nickname" />)}
</Form.Item>
<Form.Item {...formTailLayout}>
<Checkbox checked={this.state.checkNick} onChange={this.handleChange}>
Nickname is required
</Checkbox>
</Form.Item>
<Form.Item {...formTailLayout}>
<Button type="primary" onClick={this.check}>
Check
</Button>
</Form.Item>
</div>
);
}
}
const WrappedDynamicRule = Form.create({ name: 'dynamic_rule' })(DynamicRule);
ReactDOM.render(<WrappedDynamicRule />, mountNode);
複製代碼
思考:能不能只傳data和fields字段,底層不須要關心表單項的生成過程呢。react
因而,博主費盡千辛萬苦封裝了一個超好用的UForm組件,只須要傳入data、fields props和onChange、onCancel、onSubmit回調便可渲染一個完整的表單了,支持表單渲染、表單驗證、修改回調、提交回調、取消回調。git
<UForm
data={data}
fields={fields}
onChange={onChange}
onCancel={onCancel}
onSubmit={onSubmit}
/>
複製代碼
目前UForm組件支持常規表單及彈窗表單兩種,支持Form組件包含Input
、InputNumber
、Textarea
、Select
、Radio
、Checkbox
、Password
、Switch
、Rate
、custom(自定義ReactNode)
。github
documentation:dadaiwei.github.io/uform
npm:www.npmjs.com/package/ufo…npm
1.安裝 UForm 依賴包bash
npm install uform --save-dev
複製代碼
2.引入依賴包antd
import UForm from "uform";
import "uform/dist/uform.css";
複製代碼
3.使用 UForm 組件app
<UForm
data={data}
fields={fields}
onChange={onChange}
onCancel={onCancel}
onSubmit={onSubmit}
/>
複製代碼
代碼佈局
import React, { useState } from "react";
import UForm from "uform";
import "uform/dist/uform.css";
function NormalForm() {
const [data, setData] = useState({
name: "",
size: 1,
city: 0,
area: "郊區",
password: "",
choosen: true,
confirm: true,
rate: 3,
describe: ""
});
const fields = [
{
name: "name",
label: "名稱",
type: "input",
placeholder: "請輸入名稱",
rules: [
{
required: true,
message: "請輸入名稱"
}
]
},
{
name: "size",
label: "大小",
type: "inputNumber",
placeholder: "請輸入大小",
rules: [
{
required: true,
message: "請輸入名稱"
}
]
},
{
name: "city",
label: "城市",
type: "select",
fieldData: [
{
name: "北京",
value: 0
},
{
name: "上海",
value: 1
},
{
name: "杭州",
value: 2
},
{
name: "深圳",
value: 3
}
],
rules: [
{
required: true,
message: "請輸入名稱"
}
]
},
{
name: "area",
label: "地區",
type: "radio",
fieldData: ["城區", "郊區"]
},
{
name: "confirm",
label: "確認選擇",
type: "checkbox",
rules: [
{
required: true,
message: "請確認選擇"
}
]
},
{
name: "custom",
label: "自定義項",
type: "custom",
node: (
<div>
<h2>自定義表單項</h2>
</div>
)
},
{
name: "password",
label: "密碼",
type: "password",
rules: [
{
required: true,
message: "請輸入密碼"
}
]
},
{
name: "choosen",
label: "是否選擇",
type: "switch",
checkedChildren: "開",
unCheckedChildren: "關",
rules: [
{
required: true,
message: "請輸入密碼"
}
]
},
{
name: "rate",
label: "評分",
type: "rate"
},
{
name: "describe",
label: "描述",
type: "textarea",
placeholder: "請輸入描述"
}
];
const onChange = (result) => {
setData({
...data,
...result
});
};
const onSubmit = (values) => {
console.log(values);
};
const onCancel = () => {
console.log("cancel");
};
return (
<div>
<div style={{ width: 600, marginLeft: 100 }}>
<UForm
data={data}
fields={fields}
onChange={onChange}
onCancel={onCancel}
onSubmit={onSubmit}
/>
</div>
</div>
);
}
複製代碼
代碼
import React, { useState } from "react";
import { Button } from "antd";
import UForm from "uform";
import "uform/dist/uform.css";
function ModalForm() {
const { visible, setVisible } = useState(false);
const [data, setData] = useState({
name: "",
size: 1,
city: 0,
area: "郊區",
password: "",
choosen: true,
confirm: true,
rate: 3,
describe: ""
});
const fields = [
{
name: "name",
label: "名稱",
type: "input",
placeholder: "請輸入名稱",
rules: [
{
required: true,
message: "請輸入名稱"
}
]
},
{
name: "size",
label: "大小",
type: "inputNumber",
placeholder: "請輸入大小",
rules: [
{
required: true,
message: "請輸入名稱"
}
]
},
{
name: "city",
label: "城市",
type: "select",
fieldData: [
{
name: "北京",
value: 0
},
{
name: "上海",
value: 1
},
{
name: "杭州",
value: 2
},
{
name: "深圳",
value: 3
}
],
rules: [
{
required: true,
message: "請輸入名稱"
}
]
},
{
name: "area",
label: "地區",
type: "radio",
fieldData: ["城區", "郊區"]
},
{
name: "confirm",
label: "確認選擇",
type: "checkbox",
rules: [
{
required: true,
message: "請確認選擇"
}
]
},
{
name: "custom",
label: "自定義項",
type: "custom",
node: (
<div>
<h2>自定義表單項</h2>
</div>
)
},
{
name: "password",
label: "密碼",
type: "password",
rules: [
{
required: true,
message: "請輸入密碼"
}
]
},
{
name: "choosen",
label: "是否選擇",
type: "switch",
checkedChildren: "開",
unCheckedChildren: "關",
rules: [
{
required: true,
message: "請輸入密碼"
}
]
},
{
name: "rate",
label: "評分",
type: "rate"
},
{
name: "describe",
label: "描述",
type: "textarea",
placeholder: "請輸入描述"
}
];
const onChange = (result) => {
setData({
...data,
...result
});
};
const onSubmit = (values) => {
console.log(values);
};
const onCancel = () => {
setVisible(false);
};
return (
<div>
<Button
type='primary'
onClick={() => {
setVisible(true);
}}>
打開彈窗表單
</Button>
<div style={{ width: 600, marginLeft: 100 }}>
<UForm
type="modal"
visible={visible}
title='新建表單'
data={data}
fields={fields}
onChange={onChange}
onCancel={onCancel}
onSubmit={onSubmit}
/>
</div>
</div>
);
}
複製代碼
屬性 | 說明 | 必填屬性 | 類型 | 可選值 | 默認值 |
---|---|---|---|---|---|
type | 使用通用表單或者彈框表單 | false | string | norma | modal | normal |
layout | 表單佈局 | false | string | horizontal | vertical | inline | horizontal |
labelCol | 表單 label 佔寬 | false | number | 1-24 之間整數 | 4 |
wrapperCol | 表單內容項佔寬 | false | number | 1-24 之間整數,一般爲 24-labelCol | 16 |
loading | 肯定按鈕 loading | false | boolean | true | false | false |
data | 表單數據 | true | any[ ] | - | [ ] |
fields | 表單每一項特徵描述 | true | any[ ] | - | [ ] |
onSubmit | 表單提交回調 | true | Function(values) | - | 無 |
onChange | 表單每一項修改回調 | false | Function(value) | - | 無 |
onCancel | 表單取消回調 | false | Function( ) | - | 無 |
屬性 | 說明 | 必填屬性 | 類型 | 可選值 | 默認值 |
---|---|---|---|---|---|
name | 表單數據 name,與 data 中 key 值一致 | true | string | - | 無 |
type | 表單項類型 | true | string | input | inputNumber | textarea | select | radio | checkbox | password | switch | rate | custom(自定義項) | 無 |
label | 表單項 label | true | string | - | 無 |
rules | 表單項限制規則,與 antd Form 限制規則一致 | false | object [ ] | - | 無 |
fieldData | 適用於 type 爲 select/radio 的選擇項 | true | object [ ] | - | 無 |
placehoder | 適用於 type 爲 input/textarea/select 的提示信息 | false | string | - | 無 |
node | 適用於 type 爲 custom 的自定義 ReactNode | true | ReactNode | - | 無 |
特別說明:type 類型爲 select/radio時, fieldsData 是必填屬性, type 類型爲 custome 時, node 是必填屬性。
屬性 | 說明 | 必填屬性 | 類型 | 可選值 | 默認值 |
---|---|---|---|---|---|
showCancelButton | 是否展現取消按鈕 | false | boolean | true | false | true |
屬性 | 說明 | 必填屬性 | 類型 | 可選值 | 默認值 |
---|---|---|---|---|---|
visible | 彈框是否可見 | true | boolean | true | false | true |
title | 彈框標題 | true | string | ReactNode | - | 無 |
width | 彈框寬度 | false | number | - | 600 |
以上就是博主基於antd Form組件封裝的UForm組件,目前支持功能還比較簡單,後續會逐漸完善擴展該組件的功能,感興趣的小夥伴能夠試用下,真的簡單又好用。
以爲文章不錯的小夥伴能夠點個贊,灰常感謝^_^。