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

相关文章
|
2月前
|
JSON Java 数据安全/隐私保护
java中的http请求的封装(GET、POST、form表单、JSON形式、SIGN加密形式)
java中的http请求的封装(GET、POST、form表单、JSON形式、SIGN加密形式)
131 1
|
17天前
|
JavaScript 前端开发
react18【系列实用教程】双向绑定表单 (2024最新版)含受控组件、非受控组件、单行多行输入框 input,下拉选择 select,单选 radio,多选 checkbox,标签 label
react18【系列实用教程】双向绑定表单 (2024最新版)含受控组件、非受控组件、单行多行输入框 input,下拉选择 select,单选 radio,多选 checkbox,标签 label
30 1
|
25天前
|
JSON 关系型数据库 MySQL
MySQL中GROUP_CONCAT与JSON_OBJECT、GROUP BY的巧妙结合:打造高效JSON数组汇总
MySQL中GROUP_CONCAT与JSON_OBJECT、GROUP BY的巧妙结合:打造高效JSON数组汇总
16 1
|
2月前
|
监控 前端开发 搜索推荐
react 表单受控的现代实现方案
`react-form-simple`是一个轻量级的React表单库,专注于简化受控表单的开发,提供数据绑定、验证、错误处理和UI更新等功能。它通过简洁的API减少复杂性,支持第三方UI库集成,并具备高度可扩展性。核心特点包括基于Proxy的数据绑定、实时错误处理、高效的UI更新和灵活的使用方式。通过`useForm`和`render`等钩子,开发者可以快速构建表单应用,同时支持动态表单和自定义验证规则。该库旨在提高开发效率,适用于复杂表单场景,降低学习和维护成本。
177 2
react 表单受控的现代实现方案
|
17天前
|
前端开发
Vue3 【仿 react 的 hook】封装 useTitle
Vue3 【仿 react 的 hook】封装 useTitle
9 0
|
17天前
|
前端开发 API
Vue3 【仿 react 的 hook】封装 useLocation
Vue3 【仿 react 的 hook】封装 useLocation
10 0
|
1月前
|
前端开发 API
|
22天前
|
机器学习/深度学习 JSON 移动开发
详细解读BootStrap智能表单系列八表单配置json详解
详细解读BootStrap智能表单系列八表单配置json详解
10 0
|
1月前
|
存储 前端开发 数据可视化
React 中重新实现强制实施表单
React 中重新实现强制实施表单
|
26天前
|
机器学习/深度学习 JSON 移动开发
详细解读BootStrap智能表单系列八表单配置json详解
详细解读BootStrap智能表单系列八表单配置json详解
13 0