前言

由于一直在做中台业务,后台项目特别多,但是后台项目的特点是:大量的列表和大量表单,重复开发会降低效率,所以我这边总结了一下使用antd组件搭建form的快捷方法。希望能对大家有用。

传统Form搭建

首先传统搭建一个form表单,那么代码可能会是下面这样子

import React from 'react';

import { Form, Input } from 'antd';

@Form.create()

class MyTestForm extends React.Component {

render() {

const { form: { getFieldDecorator } } = this.props;

return(

{

getFieldDecorator('username', {

rules: [

{

required: true,

message: '这是必填项'

}

]

})()

}

{

getFieldDecorator('password', {

rules: [

{

required: true,

message: '这是必填项'

}

]

})()

}

)

}

}

export default MyTestForm;

目前只有两个表单项,看起来代码还挺清晰的,假如这个表单是很复杂的表单,有多个表单项,这块的代码会很长,维护和开发起来都是不方便,最重要的再来一个大的表单,你还是会需要写这么多的代码。这样就影响了开效率。

优化后的Form

我们想要的是,尽量少写(不写)重复性的代码,让代码的复用性更高。我这块做了一些优化,主要的流程如图:

主要的几个点:将最底层,最重要的部分抽离出来,也就是BaseItem组件,BaseItem具备的能力是form的能力,双向绑定的能力等,这是个纯净的组件,不包含任何UI层面的东西。

UI层的东西也单独抽离出来,以方便以后UI层面的拓展。(例如想自己设计一套UI样式,就只用直接新开发一套UI层面的东西,而不用担心原子层组件的代码)。

每个表单的信息抽离成配置文件,使页面维护起来更方便。

具体的代码如下

//BaseItem.js(原子层)const BaseItem = (props) => {

const { form: { getFieldDecorator }, config } = props;

const { name, children, ...argv } = config;

return name ? getFieldDecorator(name, { ...argv })(children) : (children);

}

export default BaseItem;

//ItemLayout.js(UI组件)import React from 'react';

import { Form } from 'antd';

//Layout也可以用自己的UI组件const Layout = ({ config: { itemOptions }, children }) =>

{ children }

const hidden = (isHidden) => {

const type = typeof(isHidden);

return (type === 'function' && isHidden()) || type === undefined || isHidden;

//默认是显示}

class ItemLayout extends React.Component {

render() {

const { children } = this.props;

return(

<>

{

React.Children.map(

children, (child, i) => {

const { config: { isHidden, ...argv}} = child.props;

return hidden(isHidden) ? null : //具有隐藏表单项能力 React.cloneElement(

{ child },

{

...children.props

}

)

}

)

}

>

)

}

}

export default ItemLayout;

//config.js(配置文件)import React from 'react';

import { Input } from 'antd';

export const formConfig = () => {

return [

{

itemOptions : { //Form.Item的api配置 label: '姓名'

//...argv },

name: 'username',

initialValue: '',

rules: [],

children:

//...argv },

{

itemOptions : {

label: '密码'

},

name: 'password',

initialValue: '',

rules: [],

children: ,

isHidden: true //隐藏此项 默认是显示 },

{

itemOptions : {

label: '密码'

},

name: 'password',

initialValue: '',

rules: [],

children: ,

isHidden: () => false //通过方法来动态显示隐藏 },

]

}支持antd Form 所有的api。

配置文件为什么是使用函数的形式?因为可以通过函数的参数,实现配置文件和页面之间进行数据的传递。

在页面就这样使用,代码如下

import React from 'react';

import { Form, Input } from 'antd';

import { formConfig } from './config.js';

import BaseItem from './BaseItem';

import ItemLayout from './ItemLayout';

@Form.create()

class MyTestForm extends React.Component {

render() {

const { form } = this.props;

return(

{

formConfig().map((item, i) =>

)

}

)

}

}

export default MyTestForm;

相比传统搭建Form是不是快捷了很多,而且页面代码层面更显得更清晰。注意:

假如是想使用自定义的组件,(一个个性化的业务组件),简单点,我对的封装

//自动trim的Inputimport { Component } from 'react';

import { Input } from 'antd';

class TrimInput extends Component {

handleChange = (e) => {

e.target.value = e.target.value.trim();

this.props.onChange(e.target.value); //Input Chang 后将值传递给props}

render() {

const { value, ...argv } = this.props;

return(

value={ value } //将props的填在Input中 { ...argv }

onChange={this.handleChange}/>

)

}

}

export default TrimInput;自定义的业务组件需要具备双向数据流的能力,最重要的一点是在更新的时候需要 调用this.props.onChange(data)。

搜索Form包装(SearchForm)

假如觉得这还不够过瘾,那么一起来基于BaseItem来再包装业务组件吧。相信每个后台都有搜索能力吧,那么我们就包装一个搜索的SearchForm。

主要就是增加一个search功能并把form的值传递出去。

主要代码如下:

//searchForm.jsimport React from 'react';

import { Form, Button } from 'antd';

import BaseItem from './BaseItem';

import ItemLayout from './ItemLayout';

@Form.create()

class SearchForm extends React.Component {

handleSearch = () => {

const { form: { validateFields }, search } = this.props;

validateFields((err, fieldsValue) => {

console.log(fieldsValue);

if(!err) {

search && search(fieldsValue);

}

})

}

render() {

const { form, searchConfig, search, form: { resetFields } } = this.props;

return(

<>

{

searchConfig().map((item, i) =>

)

}

{

search &&

搜索

resetFields()}>重置

}

>

)

}

}

export default SearchForm;

页面里面使用,表单项还是抽成配置文件使用:

//config.js 查询条件export const searchConfig = () => {

return [

{

itemOptions : {

label: '条件一'

},

name: 'name1',

initialValue: '',

rules: [],

children:

},

{

itemOptions : {

label: '条件二'

},

name: 'name2',

initialValue: '',

rules: [],

children:

}

]

}

import React from 'react';

import { searchConfig } from './config';

import SearchForm from './SearchForm';

class MyTestForm extends React.Component {

handleSearch = value => {

console.log(value);//获取到的查询条件}

render() {

return(

)

}

}

export default MyTestForm;

这样子写查询表单是不是很快呀,以后遇到查询就引用这个组件,然后抽一个配置文件,这样就OK了。

antd Form 需要注意的几个问题。initialValue 这个属性只是设置表单的初始值,当需要动态更改表单的值的时候,使用 setFieldsValue

resetFields这个属性是重置一组输入控件的值与状态,(将值重置为initialValue , 而不是清空数据,需要清空数据还是使用setFieldsValue)

antd Form 新的改动

antd Form 将在第4个版本使用 rc-field-form, 但是还没有发布,我是在4.0-prepare分支上看到。

那么两个底层组件 有什么区别呢?

首先rc-field-form 会尽量在api层面上保持一致,但是仍有地方做了改动。主要是以下几点:当没有手动更新过表单的时候,将不会收集initialValues 的值

在rc-form里面,如果用户没有操作过表单,将会从form的initialValues 收集值。他们认为这是一个bug,但是好多用户是用了这个,所以他们不做修复。在rc-field-form中,将不会有这个bug。如果想改变组件的值,使用 setFieldsValue 代替。

嵌套的name使用数组代替字符串

rc-form里面支持user.name,最终会被解释成为{user:{ name: '' } }

rc-field-form将是['user', 'name'] 解释成为 {user: { name: '' }} 并且会把 user.name解释成为{ ['user.name']: ''}

删除validateFieldsAndScroll这个属性

是因为使用了findDomNode,但是findDomNode在StrictMode中被标记为警告。认为这是对表单组件的过度控制。

getFieldsError 将总是返回来数组

rc-form 当没有错的时候,返回的是null,rc-field-form现在返回的是一个空数组

// 删除了validateFields的callback函数// 是因为ES8支持async/await,没有理由不使用它。我们使用的时候应该是async function() {

try {

const values = await form.validateFields();

console.log(values);

} catch (errorList) {

errorList.forEach(({ name, errors }) => {

// Do something... });

}

}setFields将不触发onFieldsChange和setFieldsValue不触发onValuesChange

总结

写这篇文章主要是自己做后台的Form的总结,还有是为大家提供一种思路,后台快速开发的方式。

后面还会更新其它antd 组件,主要是如何开发更适合业务场景的组件。

antd提交表单_antd快速开发(Form篇)相关推荐

  1. Antd Vue 表单生成快速开发指南,内附强大的表单设计器

    之前发布了一款基于Element的表单设计器,可以快速设计和生成表单,设计器地址:http://form.making.link/.现在我可以告诉大家,Antd表单支持来了,可以使用设计器设计好表单后 ...

  2. antd提交表单_表单序列化

    随着 Ajax 的出现,表单序列化已经成为一种常见需求.在 JavaScript 中,可 以利用表单字段的 type 属性,连同 name 和 value 属性一起实现对表单的序列化.在编写代码之前, ...

  3. ajax提交表单跨域啊,form表单提交没有跨域问题,但ajax提交存在跨域问题

    浏览器的策略本质是:一个域名下面的JS,没有经过允许是不能读取另外一个域名的内容,但是浏览器不阻止你向另外一个域名发送请求. 所以form表单提交没有跨域问题,提交form表单到另外一个域名,原来页面 ...

  4. java 提交表单_http常见的form表单请求方式

    在Web开发中,我们使用的比较多的HTTP请求方式基本上就是GET.POST. 一.http请求常见的表单文件上传形式 首先了解下application/x-www-form-urlencoded和m ...

  5. php js 防止重复提交表单,php如何防止form重复提交

    php如何防止form重复提交 引入cookie机制来解决(推荐学习:PHP编程从入门到精通) 用户提交表单到后端,在 Cookie 中做标记,指定时间内重复提交无效.但是用户禁用 Cookie 这个 ...

  6. Spring boot + maven + jetty9在提交表单的时候出现Form too large

    使用Spring boot + maven + jetty9 提交表单的时候,表单过长时,会在org.eclipse.jetty.server.Requset抛出Form too large:XXX ...

  7. layui提交表单自动刷新_layui form表单提交后实现自动刷新

    刚刚使用layui 来做东西,对这一切都不熟悉,使用一下form表单,但是,不能成功的使用. 问题: 1.提交表单,页面自动刷新. 出现这样的情况呢,搜索了一下是因为表单的提交按钮没有type类型.哪 ...

  8. php 提交表单跳转页面,form表单页面跳转方式提交练习

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 //form表单提交练习 /*新建一个form.html网页用来书写前端HTML表单*/ 表单提交练习 姓名: 年龄: 电话: 地址: QQ: 自我评价: ...

  9. antd提交表单_antd-form表单操作

    const{getFieldDecorator}=this.props.form; const formItemLayout={ labelCol:{ xs:{span:24}, sm:{span:6 ...

最新文章

  1. mysql跨库查询 索引_MySQL中跨库查询怎么搞?
  2. 2021年中国硬核创业者调研报告
  3. hadoop 替代方案_如何通过比较替代方案做出有效的决定
  4. mysql ---- DQL(单表查询)
  5. 2021-2025年中国短脉冲激光器行业市场供需与战略研究报告
  6. Local Database Overview for Windows Phone
  7. 分解原理_原理篇 | 推荐系统之矩阵分解模型
  8. Python爬虫-模拟登入-selenium模块
  9. 年会抽奖 - 牛客网题解
  10. 2011年戴尔服务器型号,PowerEdge 11G R310机架式服务器
  11. php阴阳万年历转换的接口,万年历接口
  12. HTML简单动画制作
  13. 【VS Nuget包数据源无效】
  14. 简单粗暴清理C盘办法
  15. Bugku--散乱的密文
  16. Transform 转换
  17. 射频原理图设计checklist
  18. 理论+实操 :部署YUM仓库以及NFS资源共享服务————理论讲解
  19. SAP ABAP——数据类型(一)【数据类型概要及分类】
  20. lane是什么意思_lane是什么意思_lane的翻译_音标_读音_用法_例句_爱词霸在线词典...

热门文章

  1. 传统弓上弦的几种方式
  2. 广东高考成绩及录取分数线揭晓
  3. 百度编辑支持word内容和截图的复制黏贴
  4. linux设备模型--sysfs
  5. 蒙特卡洛方法 (Monte Carlo Method)(5)
  6. 基于循环神经网络的格兰杰因果网络重构
  7. twitter开源_30位开源社区经理将在Twitter上关注
  8. 安装多可预览控件后,不能正常预览和修改该怎么办?
  9. 基于K-均值的app列表聚类分析
  10. 美国国土安全部仍然使用COBOL语言