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月前
|
前端开发 JavaScript 网络架构
react对antd中Select组件二次封装
本文介绍了如何在React中对Ant Design(antd)的Select组件进行二次封装,包括创建MSelect组件、定义默认属性、渲染Select组件,并展示了如何使用Less进行样式定义和如何在项目中使用封装后的Select组件。
164 2
react对antd中Select组件二次封装
|
5月前
|
前端开发
React添加路径别名alias、接受props默认值、并二次封装antd中Modal组件与使用
本文介绍了在React项目中如何添加路径别名alias以简化模块引入路径,设置组件props的默认值,以及如何二次封装Ant Design的Modal组件。文章还提供了具体的代码示例,包括配置Webpack的alias、设置defaultProps以及封装Modal组件的步骤和方法。
114 1
React添加路径别名alias、接受props默认值、并二次封装antd中Modal组件与使用
|
4月前
|
JSON JavaScript API
(API接口系列)商品详情数据封装接口json数据格式分析
在成长的路上,我们都是同行者。这篇关于商品详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦!
|
4月前
|
前端开发
react 封装防抖
react 封装防抖
42 4
|
5月前
|
JSON 前端开发 中间件
React读取properties配置文件转化为json对象并使用在url地址中
本文介绍了如何在React项目中读取properties配置文件,将其内容转化为JSON对象,并在请求URL地址时使用这些配置。文章详细说明了异步读取文件、处理字符串转换为JSON对象的过程,并提供了一个封装函数,用于在发起请求前动态生成配置化的URL地址。
121 1
|
5月前
封装react-antd-table组件参数以及方法如rowSelection、pageNum、pageSize、分页方法等等
文章介绍了如何封装React-Antd的Table组件,包括参数和方法,如行选择(rowSelection)、页码(pageNum)、页面大小(pageSize)、分页方法等,以简化在不同表格组件中的重复代码。
104 0
|
5月前
|
人工智能 前端开发 JavaScript
react js 处理表单( form )的2个例子
react js 处理表单( form )的2个例子
|
7月前
|
JSON Java fastjson
Spring Boot返回Json数据及数据封装
本文详细介绍了如何在Spring Boot项目中处理JSON数据的传输 Spring Boot默认使用Jackson作为JSON处理器,并通过`spring-boot-starter-web`依赖自动包含相关组件。文章还展示了如何配置Jackson处理null值,使其转换为空字符串。此外,文章比较了Jackson和FastJson的特点,并提供了FastJson的配置示例,展示了如何处理null值以适应不同应用场景。
|
7月前
|
前端开发
Vue3 【仿 react 的 hook】封装 useTitle
Vue3 【仿 react 的 hook】封装 useTitle
67 0
|
7月前
|
前端开发 API
Vue3 【仿 react 的 hook】封装 useLocation
Vue3 【仿 react 的 hook】封装 useLocation
50 0