1313
14141 . 基于 js 配置开发 ant design 表单项
15152 . 支持 Grid, Flex, Space 三种布局
16- 3 . 支持表单联动
17- 4 . 支持全量渲染 / 局部渲染
18- 5 . 支持动态增 / 删 / 改表单项目
19- 6 . 与 react 数据驱动视图理念保持一致` UI=F(state) `
20- 7 . 基于 react-hooks
21- 8 . 使用 typescript 编写,开发智能提示
16+ 3 . 与 react 数据驱动视图理念保持一致` UI=F(state) `
17+ 4 . 基于 react-hooks
18+ 5 . 使用 typescript 编写,开发智能提示
2219
2320## 示例
2421
@@ -34,47 +31,32 @@ import { GridRender } from 'antd-form-render';
3431const GridOneColumn = () => {
3532 const [form] = Form .useForm ();
3633
37- const oneColumn = [
34+ const layout : Item [] = [
3835 {
39- type: Input ,
4036 label: ' 手机号' ,
41- placeholder: ' 请输入' ,
4237 name: ' tel' ,
43- elProps: {
44- maxLength: 11 ,
45- },
46- itemProps: {
47- rules: [
48- { required: true , message: ' 请输入' },
49- { pattern: / ^ 1\d {10} $ / , message: ' 手机号必须为11位数字' },
50- ],
51- },
38+ rules: [{ required: true , message: ' 请输入' }],
39+ element: <Input placeholder = " 请输入" maxLength = { 11 } />,
5240 },
5341 {
54- type: Input .Password ,
5542 label: ' 密码' ,
56- placeholder: ' 请输入' ,
5743 name: ' pwd' ,
58- itemProps: {
59- rules: [{ required: true , message: ' 请输入' }],
60- },
44+ element: <Input.Password placeholder = " 请输入" ></Input.Password >,
6145 },
6246 {
63- render() {
64- return (
65- <div style = { { display: ' flex' , justifyContent: ' flex-end' }} >
66- <Button type = " primary" htmlType = " submit" style = { { width: 120 }} >
67- 登录
68- </Button >
69- </div >
70- );
71- },
47+ element : (
48+ <Flex justify = " flex-end" >
49+ <Button type = " primary" htmlType = " submit" >
50+ 保存
51+ </Button >
52+ </Flex >
53+ ),
7254 },
7355 ];
7456
7557 return (
76- <Form form = { form } labelCol = { { span: 4 }} labelAlign = " left " >
77- <GridRender layout = { oneColumn } />
58+ <Form form = { form } layout = " vertical " style = { { width: 400 }} >
59+ <GridRender layout = { layout } />
7860 </Form >
7961 );
8062};
@@ -97,12 +79,9 @@ const GridNColumns = () => {
9779
9880 for (let i = 0 ; i < 11 ; i ++ ) {
9981 layout .push ({
100- type: Input ,
10182 label: ` 输入框${i + 1 } ` ,
10283 name: ` name${i } ` ,
103- elProps: {
104- placeholder: ' 请输入' ,
105- },
84+ element: <Input placeholder = " 请输入" />,
10685 });
10786 }
10887
@@ -120,11 +99,8 @@ const GridNColumns = () => {
12099 <Radio value = { 4 } >1行4列</Radio >
121100 </Radio.Group >
122101 </div >
123- <GridRender
124- layout = { layout }
125- columnCount = { cols }
126- gutter = { [8 , 8 ]}
127- ></GridRender >
102+
103+ <GridRender layout = { layout } columnCount = { cols } gutter = { [8 , 8 ]} />
128104 </Form >
129105 );
130106};
@@ -142,26 +118,33 @@ import { Input, Radio, Form, Button } from 'antd';
142118import { SpaceRender } from ' antd-form-render' ;
143119
144120const SpaceLayout = () => {
121+ const [form] = Form .useForm ();
145122 const layout: Item [] = [];
146123 const [space, setSpace] = useState (8 );
147124
148125 for (let i = 0 ; i < 3 ; i ++ ) {
149126 layout .push ({
150127 name: ` name${i } ` ,
151- type: Input ,
152128 label: ` 输入框${i + 1 } ` ,
153- elProps: {
154- placeholder: ' 请输入' ,
155- },
129+ element: <Input placeholder = " 请输入" />,
156130 });
157131 }
158132
159133 layout .push ({
160- render : () => <Button type = " primary" >submit</Button >,
134+ element : (
135+ <Button
136+ type = " primary"
137+ onClick = { () => {
138+ console .log (form .getFieldsValue ());
139+ }}
140+ >
141+ submit
142+ </Button >
143+ ),
161144 });
162145
163146 return (
164- <Form layout = " horizontal" >
147+ <Form form = { form } layout = " horizontal" >
165148 <div style = { { marginBottom: 24 }} >
166149 <Radio.Group
167150 onChange = { (e ) => setSpace (Number (e .target .value ))}
@@ -174,7 +157,8 @@ const SpaceLayout = () => {
174157 <Radio value = { 32 } >32px</Radio >
175158 </Radio.Group >
176159 </div >
177- <SpaceRender layout = { layout } size = { space } ></SpaceRender >
160+
161+ <SpaceRender layout = { layout } size = { space } />
178162 </Form >
179163 );
180164};
@@ -192,6 +176,7 @@ import { Input, Radio, Form, Button } from 'antd';
192176import { FlexRender , Item } from ' antd-form-render' ;
193177
194178const FlexLayout = () => {
179+ const [form] = Form .useForm ();
195180 const layout: Item [] = [];
196181 const [gap, setGap] = useState (8 );
197182
@@ -207,11 +192,20 @@ const FlexLayout = () => {
207192 }
208193
209194 layout .push ({
210- render : () => <Button type = " primary" >submit</Button >,
195+ element : (
196+ <Button
197+ type = " primary"
198+ onClick = { () => {
199+ console .log (form .getFieldsValue ());
200+ }}
201+ >
202+ submit
203+ </Button >
204+ ),
211205 });
212206
213207 return (
214- <Form layout = " horizontal" >
208+ <Form form = { form } layout = " horizontal" >
215209 <div style = { { marginBottom: 24 }} >
216210 <Radio.Group
217211 onChange = { (e ) => setGap (Number (e .target .value ))}
@@ -224,12 +218,11 @@ const FlexLayout = () => {
224218 <Radio value = { 32 } >32px</Radio >
225219 </Radio.Group >
226220 </div >
221+
227222 <FlexRender layout = { layout } gap = { gap } justify = " flex-end" />
228223 </Form >
229224 );
230225};
231-
232- export default FlexLayout ;
233226```
234227
235228#### 表单联动
@@ -240,104 +233,51 @@ export default FlexLayout;
240233![ image] ( ./imgs/dep-update.png )
241234
242235``` tsx
243- import React , { useState } from ' react' ;
244- import { Form , Radio } from ' antd' ;
245- import { GridRender } from ' antd-form-render' ;
236+ import React from ' react' ;
237+ import { Form , Radio , Divider } from ' antd' ;
238+ import { GridRender , Item } from ' antd-form-render' ;
246239
247240const DynamicRender = () => {
248241 const [form] = Form .useForm ();
249- const [form1] = Form .useForm ();
250242
251- // #region 全量渲染联动
252-
253- // 用于同步表单状态
254- const [data, setData] = useState <{ gender? : string }>({});
255-
256- const layout = [
243+ const layout: Item [] = [
257244 {
258- type: Radio .Group ,
259245 label: ' 性别' ,
260246 name: ' gender' ,
261- elProps: {
262- options: [
263- { label: ' 男' , value: ' 男生' },
264- { label: ' 女' , value: ' 女生' },
265- ],
266- },
247+ element : (
248+ <Radio.Group
249+ options = { [
250+ { label: ' 男' , value: ' 男生' },
251+ { label: ' 女' , value: ' 女生' },
252+ ]}
253+ />
254+ ),
267255 },
268256 {
269- type: ' div' ,
270- label: ' 你是' ,
271- elProps: {
272- children: data ?.gender || ' 未选择' ,
273- },
257+ element: <Divider orientation = " left" > element() </Divider >,
274258 },
275- ];
276-
277- // #endregion 全量渲染联动
278-
279- // #region 局部联动渲染
280-
281- // 基于Form.Item dependency/shouldUpdate 实现表单联动,局部渲染
282- const layout1 = [
283259 {
284- type: Radio .Group ,
285- label: ' 性别' ,
286- name: ' gender' ,
287- elProps: {
288- options: [
289- { label: ' 男' , value: ' 男生' },
290- { label: ' 女' , value: ' 女生' },
291- ],
292- },
260+ element : () =>
261+ form .getFieldValue (' gender' ) && (
262+ <div > 你的性别(element()) { form .getFieldValue (' gender' )} </div >
263+ ),
293264 },
294265 {
295- render() {
296- // dependencies
297- return (
298- <Form.Item label = " 你是" dependencies = { [' gender' ]} >
299- { () => {
300- const gender = form1 .getFieldValue (' gender' );
301- return gender || ' 未选择' ;
302- }}
303- </Form.Item >
304- );
305- },
266+ element: <Divider orientation = " left" > render() </Divider >,
306267 },
307268 {
308- render() {
309- // shouldUpdate
310- return (
311- <Form.Item shouldUpdate label = " 你是" >
312- { () => {
313- return form1 .getFieldValue (' gender' );
314- }}
315- </Form.Item >
316- );
317- },
269+ render : () =>
270+ form .getFieldValue (' gender' ) && (
271+ <div > 你的性别(render()) { form .getFieldValue (' gender' )} </div >
272+ ),
318273 },
319274 ];
320275
321- // #endregion 局部联动渲染
322-
323276 return (
324277 <div >
325- <p >1.定义onValuesChange 同步状态到state , 触发全量渲染实现表单联动</p >
326-
327- <Form
328- form = { form }
329- onValuesChange = { (v ) => {
330- setData ((p ) => ({ ... p , ... v }));
331- }}
332- >
278+ <Form form = { form } >
333279 <GridRender layout = { layout } ></GridRender >
334280 </Form >
335-
336- <p >2.基于Form.Item dependency/shouldUpdate 实现表单联动,局部渲染</p >
337-
338- <Form form = { form1 } >
339- <GridRender layout = { layout1 } ></GridRender >
340- </Form >
341281 </div >
342282 );
343283};
0 commit comments