资讯专栏INFORMATION COLUMN

antd-Form4.x一个页面中多个表单处理

社区管理员 / 1467人阅读

一、前言

今天开发的时候,发现一个页面的表单其实是两个部分,其中一部分还在另一个页面引用了。这就增加代码量,所以优化下,为了重复使用这里的表单。

如图,需求就是将下面两个表单拆开,可以重复使用,实际两部分可能有很多表单,这里方便起见,只写了三个。

image.png

二、涉及到知识点

  • react hooks

  • antd 4.0(Form)

  • Promise

  • 子父组件传值和父组件调用子组件方法

三、实现方法

具体实现:我放在了Codesandbox,可以直接打开调试

  • 1、首先为了充分复用表单组件,那么就要拆分的彻底一点,不能关联太多内容。

  • 2、一个模版表单多带带作为一个组件,表单通过useForm()创建。

  • 3、在组件外部进行表单提交,分别触发,然后通过Promise.all方法获取表单数据。

  • 4、编辑的时候,可以通过props将给表单赋值,然后给子组件注册供父组件调用的方法。

四、具体操作

我们通过codesandbox来试验下,这里表单添加的比较少,可以自行增加。

新建index.js文件,表单最后显示在这里

两个表单模版:templateForm1.js templateForm2.js,由于这两个文件的内容基本一样,需要根据自己的表单内容定义,所以我们这里写了一个。

import React, { useRef } from "react"; import { Button, Divider } from "antd"; import TemplateForm1 from "./templateForm1"; import TemplateForm2 from "./templateForm2"; export default function App() {   const template1Ref = useRef();   const template2Ref = useRef();   const formItemLayout = {     labelCol: { span: 4 },     wrapperCol: { span: 10 }   };   const handleCommit = () => {     let template1Data = new Promise((resolve, reject) => {       template1Ref.current.commitForm((value) => {         resolve(value);       });     });     let template2Data = new Promise((resolve, reject) => {       template2Ref.current.commitForm((value) => {         resolve(value);       });     });     Promise.all([template1Data, template2Data]).then((res) => {       console.log("get", res);     });   };   return (     <div className="App">       <Divider orientation="left">内部信息</Divider>       <TemplateForm1 ref={template1Ref} formItemLayout={formItemLayout} />       <Divider orientation="left">外部信息</Divider>       <TemplateForm2 ref={template2Ref} formItemLayout={formItemLayout} />       <Button onClick={handleCommit}>提交</Button>     </div>   ); } 复制代码

在该文件中,我们引入了两个表单的模版,通过ref属性获取组件,通过props传入父组件的变量。

当我们调用handleCommit的时候,该函数会调用子组件定义好的commitForm的方法来获取表单的数据,获取的数据通过回调函数返回。

因为多个组件存在异步获取的问题,所以这里通过promise.all方法,获取多个表单的内容,然后统一处理。

image.png

import React, { useImperativeHandle, forwardRef } from "react"; import { Form, Input } from "antd"; const TemplateForm1 = (props, ref) => {   const { formItemLayout } = props;   const [form] = Form.useForm();   useImperativeHandle(ref, () => ({     commitForm: (cb) => {       handleCommit(cb);     }   }));   const handleCommit = async (cb) => {     try {       const values = await form.validateFields();       cb(values);     } catch (err) {       console.log(err);     }   };   return (     <Form form={form} {...formItemLayout}>       <Form.Item         name="Name"         label="名称"         rules={[{ required: true, message: "请输入名称" }]}       >         <Input placeholder="点输入名称" />       </Form.Item>     </Form>   ); }; export default forwardRef(TemplateForm1); 复制代码

这个组件是我们定义的表单模版,正常读取后,通过asyncawait获取表单内容,最后再通过commitForm方法,返回给父组件。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/127958.html

相关文章

  • H5项目常见问题及注意事项

    摘要:解决方案可以解决在手机上点击事件的延迟的模块,事件也是为了解决在的延迟问题显示屏原理及设计方案说明屏是一种具备超高像素密度的液晶屏,同样大小的屏幕上显示的像素点由个变为多个,如在同样带下的屏幕上,苹果设备的显示屏中,像素点个变为个。 Meta基础知识: H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 //一、HTML页面结构 // width 设置viewport宽度,为一...

    honhon 评论0 收藏0
  • H5项目常见问题及注意事项

    摘要:解决方案可以解决在手机上点击事件的延迟的模块,事件也是为了解决在的延迟问题显示屏原理及设计方案说明屏是一种具备超高像素密度的液晶屏,同样大小的屏幕上显示的像素点由个变为多个,如在同样带下的屏幕上,苹果设备的显示屏中,像素点个变为个。 Meta基础知识: H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 //一、HTML页面结构 // width 设置viewport宽度,为一...

    Little_XM 评论0 收藏0
  • H5项目常见问题及注意事项

    摘要:解决方案可以解决在手机上点击事件的延迟的模块,事件也是为了解决在的延迟问题显示屏原理及设计方案说明屏是一种具备超高像素密度的液晶屏,同样大小的屏幕上显示的像素点由个变为多个,如在同样带下的屏幕上,苹果设备的显示屏中,像素点个变为个。 Meta基础知识: H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 //一、HTML页面结构 // width 设置viewport宽度,为一...

    shiyang6017 评论0 收藏0

发表评论

0条评论

社区管理员

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<