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

相关文章
|
5天前
|
存储 JSON 前端开发
JSON数组的概念、语法和用法
JSON数组的概念、语法和用法
221 3
|
5天前
|
JSON JavaScript 前端开发
前端 ex2json 用于 vue/react/js 将 xls、xlsx、csv 文件转成 json 数组
前端 ex2json 用于 vue/react/js 将 xls、xlsx、csv 文件转成 json 数组
97 0
|
3天前
|
JSON Java 数据安全/隐私保护
java中的http请求的封装(GET、POST、form表单、JSON形式、SIGN加密形式)
java中的http请求的封装(GET、POST、form表单、JSON形式、SIGN加密形式)
|
5天前
|
存储 JSON DataWorks
DataWorks产品使用合集之DataWorks将 MongoDB 中的数组类型写入到 DataWorks 的单个字段时,表示为字符串格式而非 JSON 格式如何解决
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
26 3
|
5天前
|
存储 前端开发 JavaScript
React的表单处理:受控组件与非受控组件深入解析
【4月更文挑战第25天】React表单处理涉及受控和非受控组件。受控组件通过状态管理表单数据,每次用户输入都触发状态更新,确保数据同步,适合实时交互但可能影响性能。非受控组件不直接管理状态,数据存储在DOM中,简化代码,适用于更新不频繁的场景,但在数据验证和同步上存在挑战。开发者应根据需求灵活选择。
|
5天前
|
XML JSON Java
Android App网络通信中通过okhttp调用HTTP接口讲解及实战(包括GET、表单格式POST、JSON格式POST 附源码)
Android App网络通信中通过okhttp调用HTTP接口讲解及实战(包括GET、表单格式POST、JSON格式POST 附源码)
232 0
|
5天前
|
SQL JSON Apache
Flink问题之嵌套 json 中string 数组的解析异常如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。
229 1
|
5天前
|
JSON PHP 数据格式
php 删掉空的数组 json数据. 空数据(false 0 ““ null)
php 删掉空的数组 json数据. 空数据(false 0 ““ null)
php 删掉空的数组 json数据. 空数据(false 0 ““ null)
|
5天前
|
XML JSON 前端开发
教你怎么用ajax传数组(也可以是转为json)
教你怎么用ajax传数组(也可以是转为json)
36 0
|
5天前
|
前端开发 JavaScript API
【第46期】一文了解React表单
【第46期】一文了解React表单
13 0