react + antd 封装通过json数组形式的Form表单

简介: 最近在搞react + antd,在弄form表单的时候,觉得没写一次都要重新写一次Form, Form.Item,感觉有些麻烦;就想啊,能不能像vue+element那样通过json配置的方式,实现一个form组件

> 最近在搞react + antd,在弄form表单的时候,觉得没写一次都要重新写一次Form, Form.Item,感觉有些麻烦;就想啊,能不能像vue+element那样通过json配置的方式,实现一个form组件


## 1. 假设你已经安装好了依赖,已经可以通过react + antd搭建页面了


> 以下是我的项目主要依赖,版本不同,写法可能也有些不同:

```json

"react": "^18.1.0",

"react-dom": "^18.1.0",

"antd": "^3.26.19",

"react-router": "^3.2.0",

```


## 2.搭建Form组件模子

```js

import React from "react"

import { Form, Col, Row} from "antd"


class Index extends React.Component {


 render() {

   return (

     <Form>


     Form>

   )

 }

}

export default Form.create()(Index)

```



## 3. 老生长谈的,配合Row与Col组件

> 主要是用 Col来做Form.Item的容器

```js

const Item = Form.Item

class Index extends React.Component {

 //这个地方就是我们用来遍历父组件传过来的json数组配置,我们就定义这个配置属性是fields

 getFormField = () => {

   //这里要注意以下 form是通过Form.create()(xxx)

   const {form, getFieldDecorator, fields} = this.props

   return fields.map((item, index)=>(

     <Col key={item.field + item.label + index} >

       <Item label={item.label}>

         {

           getFieldDecorator(item.field, {

             //...表单项配置

           })(

             //表单项配置

           )

         }

       Item>

     Col>

   ))

 }


 render() {

   return (

     <Form>

       <Row gutter={24}>{this.getFormField()}Row>

     Form>

   )

 }


}

//...省略

```


## 4. fields json数组的格式制定

```js

// {label: "姓名", field: "name", attrs: {rules: [{ required: true, message: "请输入!" }], initialValue: "张三",} component: }


// 那么 getFormField 方法也就可以完善了

getFormField = () => {

 //这里要注意以下 form是通过Form.create()(xxx)

 const {form, span = 6, fields} = this.props

 const {getFieldDecorator} = form

 return fields.map((item, index)=>(

   <Col span={span} key={item.field + item.label + index} >

     <Item label={item.label}>

       {

         getFieldDecorator(item.field, {

           ...item.attrs

         })(

           item.component

         )

       }

     Item>

   Col>

 ))

}

```


## 5. 尝试一下

**父组件**

```js

//导入Form组件

import FormPage from "./components/form"

import {Input, InputNumber} from 'antd'


function App() {

 const fields = [

   { label: "姓名", field: "name", attrs: { rules: [{ required: true, message: "请输入!" }] }, component: <Input allowClear placeholder="请输入姓名" /> },

   { label: "年龄", field: "age", attrs: { rules: [{ required: true, message: "请输入!" }] }, component: <InputNumber allowClear placeholder="请输入年龄" style={{width: "100%"}}/> },

 ]


 return (

   <div className="App">

     <FormPage fields={fields}/>

   div>

 );

}

```

#### 效果预览


antd-FormPage.v1.jpg


## 6. 那么,怎么在父组件上获取组件上表单项的值呢?

### 6.1 通过ref

```js

// 父组件中创建一个ref,绑定组件

import React from "react"

import FormPage from "./components/form"

function App() {

 //创建ref对象

 const fromRef = React.createRef()

 const handleForm = ()=> {

   //使用ref对象

   formRef.current.validateFields((err, vals) => {

     if(err) return

     console.log(vals)

   })

 }


 //...省略

 return (

   <div className="App">

     // ref对象与非状态组件绑定

     <FormPage fields={fields} ref={fromRef}/>

     <div style={{textAlign: "right"}}>

       <Button type="primary" onClick={handleForm}>获取Button>

     div>

   div>

 );

}

```

#### 效果预览

antd-FormPage.v2.jpg


### 6.2 使用 rc-form 提供的 wrappedComponentRef


```js

import React, { useState} from "react"

import FormPage from "./components/form"

function App() {

 const EnhancedForm = FormPage

 //非状态组件,用hooks定义变量

 const [form, setform] = useState();


 const handleForm = ()=> {

   //使用

   form.props.form.validateFields((err, vals) => {

     if(err) return

     console.log(vals)

   })

 }


 //...省略

 return (

   <div className="App">

     <EnhancedForm wrappedComponentRef={(form) => setform(form)} fields={fields} />

     <div style={{textAlign: "right"}}>

       <Button type="primary" onClick={handleForm}>获取Button>

     div>

   div>

 );

}

```

#### 效果预览

antd-formPage.v3.jpg


### 6.3 通过回调结合组件的componentDidMount生命钩子

**这种方法需要我们稍稍改造一下FormPage组件**

```js

//...省略

class Index extends React.Component {

 //...省略

 getForm = ()=> {

   const { form} = this.props

   this.props.getForm && this.props.getForm(form)

 }

 componentDidMount() {

   this.getForm()

 }

 //...省略

}

//...省略

```

**父组件使用**

```js

import React, { useState} from "react"

import FormPage from "./components/form"

function App() {

 const [form, setform] = useState();


 const handleForm = ()=> {

   console.log(form)

   //使用

   form.validateFields((err, vals) => {

     if(err) return

     console.log(vals)

   })

 }


 //...省略

 return (

   <div className="App">

     <FormPage fields={fields} getForm={(f) => setform(f)}/>

     <div style={{textAlign: "right"}}>

       <Button type="primary" onClick={handleForm}>获取Button>

     div>

   div>

 );

}

```

#### 效果预览

antd-FormPage.v4.jpg

相关文章
|
25天前
|
移动开发 前端开发 JavaScript
React 表单与事件
10月更文挑战第10天
34 1
|
2月前
|
前端开发 JavaScript 网络架构
react对antd中Select组件二次封装
本文介绍了如何在React中对Ant Design(antd)的Select组件进行二次封装,包括创建MSelect组件、定义默认属性、渲染Select组件,并展示了如何使用Less进行样式定义和如何在项目中使用封装后的Select组件。
81 2
react对antd中Select组件二次封装
|
25天前
|
前端开发 JavaScript 数据安全/隐私保护
深入探索研究React表单
【10月更文挑战第6天】
88 57
|
8天前
|
前端开发 JavaScript
React 表单处理技巧
【10月更文挑战第24天】本文从初学者角度出发,详细介绍了 React 中表单处理的基本概念、常见问题及解决方案。涵盖受控组件与非受控组件的区别、状态更新、表单验证、多字段管理及高级技巧,通过代码示例帮助读者更好地理解和应用。
31 7
|
2月前
|
前端开发
React给antd中TreeSelect组件左侧加自定义图标icon
本文介绍了如何在React中为Ant Design的TreeSelect组件的每个树节点添加自定义图标,并解决了因缺少key属性而导致的警告问题,展示了如何通过递归函数处理treeData数据并为每个节点添加图标。
82 2
React给antd中TreeSelect组件左侧加自定义图标icon
|
2月前
|
前端开发
react使用antd中的Checkbox实现多选
在React项目中,通过Ant Design的Checkbox组件实现多选。引入Checkbox,使用Checkbox.Group来管理Checkbox,设置`value`属性绑定选中项数组,通过`onChange`更新数组。维护一个全选状态,根据选中项数量与总数决定全选按钮状态。全选按钮的`onChange`事件用于控制所有Checkbox的选中状态。
69 1
react使用antd中的Checkbox实现多选
|
2月前
|
前端开发
React添加路径别名alias、接受props默认值、并二次封装antd中Modal组件与使用
本文介绍了在React项目中如何添加路径别名alias以简化模块引入路径,设置组件props的默认值,以及如何二次封装Ant Design的Modal组件。文章还提供了具体的代码示例,包括配置Webpack的alias、设置defaultProps以及封装Modal组件的步骤和方法。
64 1
React添加路径别名alias、接受props默认值、并二次封装antd中Modal组件与使用
|
2月前
|
前端开发 JavaScript 区块链
react18函数组件+antd使用指南-使用代码集合以及报错记录汇总
本文介绍了多个React开发中常见的问题及其解决方案,包括但不限于:1)`useForm`实例未连接到任何`Form`元素的警告及解决方法;2)监听页面滚动事件的实现方式;3)React 18与antd 5.8.6中定制主题的方法;4)React结合antd 4.x版本自定义主题色的步骤;5)解决`ResizeObserver loop`相关报错的技巧;6)处理React设计表单时遇到的CDN资源加载失败问题;7)解决onClick事件传参问题;8)修复类型错误等。每部分均提供详细分析与实用代码示例,帮助开发者快速定位并解决问题。
39 2
|
2月前
|
前端开发 数据安全/隐私保护
react antd 实现修改密码(原密码,新密码,再次输入新密码,新密码增加正则复杂度校验)
文章介绍了如何在React项目中使用Ant Design实现一个修改密码的组件,包括原密码、新密码和再次输入新密码的表单项,并为新密码增加了正则表达式复杂度校验。
61 0
react antd 实现修改密码(原密码,新密码,再次输入新密码,新密码增加正则复杂度校验)
|
2月前
|
前端开发 计算机视觉
React使用antd实现可编辑单元格
React结合Ant Design实现可编辑单元格的表格组件,通过EditableRow和EditableCell封装实现单元格编辑功能,并提供saveFun回调保存编辑内容。
87 1