1、基本概述
在上一篇博客:基于Umi搭建的个人Dva脚手架(四) - 可配置的表单组件封装中,已经详细介绍了通过配置生成表单组件的方法,在开发中我们不必过分关心view层的编码,可以减少重复代码的编写,提高开发效率。列表搜索和操作类弹窗(新增、修改等)等都会应用到表单元素,因此在已有的可配置的表单组件GenerateForm的基础上进行二次封装,分别封装了可配置的搜索组件ListFilter和可配置弹窗组件GenerateModal;下边就分别对ListFilter和GenerateModal进行说明,
2、ListFilter的实现
2.1 、原型图
列表搜索的原型大致如下,如有原型布局与下图不一致,可自行调整样式文件。考虑到列表搜索时,基本上占据了屏幕的内容区,因次默认一排排列3个元素,可自行通过表单配置中的span属性去更改;
2.2 、具体实现
具体的代码实现如下。引入GenerateForm组件,用来控制表单元素的生成。
import React, {Component} from 'react'
import {Button} from 'antd';
import GenerateForm from '../GenerateForm'
import styles from './index.less'
export default class ListFilter extends React.Component {
/*搜索*/
onSearch = () => {
this.listFilter.verify((error, values) => {
if (error) {
return
}
this.props.onSearch && this.props.onSearch(values);
})
}
/*重置*/
onReset = () => {
this.getForm.resetFields();
/*对外暴露reset方法*/
this.props.onReset && this.props.onReset()
}
/*对外暴露Form的实例*/
getForm = () => {
return this.listFilter.getForm();
}
render() {
const {
filters,
hasSearchBtn = true,
hasResetBtn = true,
searchBtnText = '查询', /* 搜索按钮文案*/
resetBtnText = '清除' /* 清除按钮文案*/
} = this.props;
/*搜索列表如果没有设置, 默认为一行3个*/
filters.forEach(item => {
if (!item.span) {
item.span = 8;
}
})
return (
<div>
<div className={styles.listFilterWrap}>
<GenerateForm formSet={filters} wrappedComponentRef={el => (this.listFilter = el)}/>
<div className={styles.btnGroup}>
{hasSearchBtn && <Button type="primary" onClick={this.onSearch}>{searchBtnText}</Button>}
{hasResetBtn && <Button type="default" onClick={this.onReset}>{resetBtnText}</Button>}
</div>
</div>
</div>
)
}
}
具体的分析如下:
(1)、props属性:一共接受七个属性,分为5个属性和2个方法:
– filters:表单元素的配置,传递给GenerateForm组件,用于生成表单;
– hasSearchBtn、hasResetBtn:用于控制是否生成搜索、清楚按钮,默认都显示;
– searchBtnText、resetBtnText:用于控制搜索、清楚按钮文案,默认都显示为“查询”、“清楚”;
– onSearch、onReset:分别用来控制查询、清空按钮的事件处理;
(2)、render方法:通过GenerateForm组件生成表单元素,表单元素的配置体现在filters属性中,由于GenerateForm被Form.create()作用,因为如需调用GenerateForm内部的方法和属性,则只能通过wrappedComponentRef属性(类似于ref);
(3)、组件方法:一共提供了3个组件方法:
– onSearch :首先对表单元素校验,然后将按钮事件传递给props中的onSearch处理;
– onReset :首先清空表单元素,然后将按钮事件传递给props中的onReset处理;
– getForm :对外暴露表单的元素的form对象,在实际业务中,可能会需要调用form的一些方法,例如表单密码确认联动校验等。可以通过该方法获取到方法见ant design的api文档:https://ant-design.gitee.io/components/form-cn/#Form.create(options)
3、GenerateModal组件的实现
3.1 、原型图
弹窗的原型大致如下,如有原型布局与下图不一致,可自行调整样式文件。由于弹窗宽度有限,因此默认一排排列2个元素,可自行通过表单配置中的span属性去更改;
3.2 、具体实现
具体的代码实现如下。引入GenerateForm组件,用来控制表单元素的生成,Modal组件用来生成弹窗。
import React from 'react'
import {Modal, Button} from 'antd';
import GenerateForm from '../GenerateForm'
import styles from './index.less'
export default class GenerateModal extends React.Component {
/*确定*/
handelOk = () => {
this.generateModal.verify((error, values) => {
if (error) {
return
}
this.props.onOk && this.props.onOk(values);
})
}
/*取消*/
handelCancel = () => {
this.props.onCancel && this.props.onCancel();
}
/*对外暴露Form的实例*/
getForm = () => {
return this.generateModal.getForm();
}
render() {
const {modalForm, visible, key, title, width = 700, hasOkBtn = true, okText = '确定', hasCancelBtn = true, cancelText = '取消'} = this.props;
const modalOpts = {
visible,
key,
title,
width,
maskClosable: false,
onCancel: this.handelCancel,
footer: <div>
{hasCancelBtn && <Button onClick={this.handelCancel}>{cancelText}</Button>}
{hasOkBtn && <Button onClick={this.handelOk} type="primary">{okText}</Button>}
</div>
};
/*modal弹窗如果没有设置,默认一行2个*/
modalForm.forEach(item => {
if (!item.span) {
item.span = 12;
}
})
return (
<Modal {...modalOpts} className={styles.generateModal}>
<GenerateForm formSet={modalForm} wrappedComponentRef={el => (this.generateModal = el)}/>
</ Modal>
)
}
}
具体的分析如下:
(1)、props属性:一共接受11个属性,分为9个属性和2个方法:
– modalForm:表单元素的配置,传递给GenerateForm组件,用于生成表单;
– visible:用于控制Modal组件显示与隐藏,对应Modal组件的visible属性;
– key:用于控制Modal组件属性key,通常设置为随机数Math.random();
– title:用于控制Modal组件标题,对应Modal组件的titie属性;
– width:用于控制Modal组件的宽度,对应Modal组件的titie属性,这里默认为700,通常项目中大部分弹窗的宽度是一直,可根据时间情况更改此参数;
– hasOkBtn、hasCancelBtn:用于控制弹窗是生成确定、取消按钮,默认都显示;
– okText、cancelText:用于控制按钮文案,默认都显示为“确定”、“取消”;
– onOk、onCancel:分别用来控制确定、取消按钮的事件处理;
(2)、render方法:通过GenerateForm组件生成表单元素,表单元素的配置体现在modalForm属性中,由于GenerateForm被Form.create()作用,因为如需调用GenerateForm内部的方法和属性,则只能通过wrappedComponentRef属性(类似于ref);
(3)、组件方法:一共提供了3个组件方法:
– handelOk :首先对表单元素校验,然后将按钮事件传递给props中的onOk处理;
– handelCancel :将按钮事件传递给props中的onCancel处理;
– getForm :对外暴露表单的元素的form对象,作用同ListFilter。
具体的实例可以参考代码:https://github.com/zhengchangshun/myUmi/tree/master/src/components/business 。
上一篇:基于Umi搭建的个人Dva脚手架(四) - 可配置的表单组件封装