后台管理系统都会用到如页头搜索栏以及table展示数据,为了减少代码量以及尽量公用部分逻辑,集成对应控件并统一封装成一个组件显得十分有必要。
功能
组件依赖于moment
,使用demo依赖loadsh
做防抖。
先展示功能部分。
/**
*
* @param {页面搜索栏组件} form 前端chen
* ----避免各个页面的搜索栏各自为战的问题,统一组件,减少代码量,尽量逻辑/组件复用----
* 兼容的搜索控件:
===Button:可以添加多个button按钮;
===Input:基本使用,输入框;
===InputNumber:number输入框;
===AutoComplete:输入匹配输入框,匹配规则默认option.props.children.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1;
===Select:下拉选择器,传递selectList{id,name}或者render=>reactNode生成对应的下拉框内容;
===TreeSelect:同·Select·;
===Switch:开关按钮,默认文字为“开/关”;
===Cascader:级联选择器,例如省市区;
===WeekPicker:星期选择器;
===MonthPicker:月份选择器;
===DatePicker:日期选择器;
===RangePicker:日期间隔选择器;
===TimeRangePicker:基于timepicker二次封装的时间段选择器,onChange时额外返回permission,开始/结束时间都有值以及autoSearch时触发搜索;
*
* 使用规则:除了各个组件使用原有API,新增如下API
===searchList:搜索栏list,其中三个字段必填:tagName标签名称,key搜索键值名称,label搜索前置名称 ;
===reset:是否重置按钮,boolean值,默认true ;
===onChange:每个非button控件值改变时触发的操作,function(itemValue);
===onDateChange:对应日期/时间选择器相关onchange[moment,str]事件,方便获取对应的str,会先于onChange执行
===onSearch:触发搜索,function(fieldsValue);
===autoSearch:是否自动触发搜索,boolean值,默认false ;
===noSearchButton:是否不用搜索按钮,boolean值,默认false ;
===stopPagination:是否返回true禁止其他如table的分页器关联操作, function(boolean) ;
===onButtonClick:有其他额外button按钮时触发的操作,function(item);
*
*/
Demo
接着看下使用demo
import React, { PureComponent } from "react";
import { debounce } from "lodash"; // 防抖
import { SearchForm } from "@/components";
const searchList = [
{
tagName: "treeselect",
key: "treeSelectItem",
label: "类型",
defaultValue: null,
placeholder: "请选择",
selectList: [
{
id: 0,
name: "123",
children: [
{
id: 10,
name: "12311"
},
{
id: 11,
name: "asd11"
}
]
},
{
id: 1,
name: "asd"
}
]
},
{
tagName: "select",
key: "selectItem",
label: "类型2",
defaultValue: null,
placeholder: "请选择",
render: () => {
// render权限比selectList高
return [
{
id: 0,
name: "12311"
},
{
id: 1,
name: "asd111"
}
].map(item => {
return (
);
});
},
selectList: [
{
id: 0,
name: "123"
},
{
id: 1,
name: "asd"
}
]
},
{
tagName: "autoComplete",
key: "autoCompleteItem",
label: "标题",
dataSource: ["Burns Bay Road", "Downing Street", "Wall Street"]
},
{
tagName: "TimeRangePicker",
key: "timerangepickerItem",
label: "时间",
timeRange: {
startTime: "00:10:00",
endTime: "00:20:00"
}
}
];
export function SearchFormFunctionDemo() {
const onSearch = e => {
console.log(e);
};
return (
console.log(e), 1500)}
onSearch={debounce(e => onSearch(e), 350)}
onChange={debounce(e => console.log(e), 350)}
/>
);
}
export class SearchFormClassDemo extends PureComponent {
constructor(props) {
super(props);
this.onSearch = debounce(this.onSearch, 350);
}
onSearch = e => {
console.log(e);
};
render() {
return (
console.log(e)}
onSearch={e => this.onSearch(e)}
onChange={e => console.log(e)}
/>
);
}
}
实现封装
最后看下封装代码,其中TimeRangePicker
是之前就封装好的组件,可以看下另外一篇文章
import React, { Fragment } from "react";
import moment from "moment";
import {
Icon,
Button,
Input,
InputNumber,
AutoComplete,
Select,
message,
DatePicker,
TreeSelect,
Switch,
Cascader,
TimePicker,
Form
} from "antd";
import { TimeRangePicker } from "@/components";
const FormItem = Form.Item;
const { Option } = Select;
const { TreeNode } = TreeSelect;
const { MonthPicker, RangePicker, WeekPicker } = DatePicker;
/**
*
* @param {页面搜索栏组件} form chenhaoyin
* ----避免各个页面的搜索栏各自为战的问题,统一组件,减少代码量,尽量逻辑/组件复用----
* 兼容的搜索控件:
===Button:可以添加多个button按钮;
===Input:基本使用,输入框;
===InputNumber:number输入框;
===AutoComplete:输入匹配输入框,匹配规则默认option.props.children.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1;
===Select:下拉选择器,传递selectList{id,name}或者render=>reactNode生成对应的下拉框内容;
===TreeSelect:同·Select·;
===Switch:开关按钮,默认文字为“开/关”;
===Cascader:级联选择器,例如省市区;
===WeekPicker:星期选择器;
===MonthPicker:月份选择器;
===DatePicker:日期选择器;
===RangePicker:日期间隔选择器;
===TimeRangePicker:基于timepicker二次封装的时间段选择器,onChange时额外返回permission,开始/结束时间都有值以及autoSearch时触发搜索;
*
* 使用规则:除了各个组件使用原有API,新增如下API
===searchList:搜索栏list,其中三个字段必填:tagName标签名称,key搜索键值名称,label搜索前置名称 ;
===reset:是否重置按钮,boolean值,默认true ;
===onChange:每个非button控件值改变时触发的操作,function(itemValue);
===onDateChange:对应日期/时间选择器相关onchange[moment,str]事件,方便获取对应的str,会先于onChange执行
===onSearch:触发搜索,function(fieldsValue);
===autoSearch:是否自动触发搜索,boolean值,默认false ;
===noSearchButton:是否不用搜索按钮,boolean值,默认false ;
===stopPagination:是否返回true禁止其他如table的分页器关联操作, function(boolean) ;
===onButtonClick:有其他额外button按钮时触发的操作,function(item);
*
*/
/** formItem的getFieldDecorator配置 */
const getFieldDecoratorOps = form => {
let rules = null;
if (form.rules) {
rules = [...form.rules];
}
if (form.pattern) {
rules = [
{
pattern: form.pattern,
message: form.message || "内容不符合规则"
}
];
}
return {
initialValue: form.nextdefaultvalue || form.nextvalue,
rules
};
};
const Search = ({
searchList /** 搜索栏list,其中三个字段必填:tagName标签名称,key搜索键值名称,label搜索名称 */,
reset = true /** 重置按钮 */,
onDateChange /** 日期相关onchange[str,moment]事件,方便获取对应的str */,
onSearch /** 触发搜索 */,
autoSearch /** 自动触发搜索 */,
noSearchButton /** 不用搜索按钮 */,
stopPagination /** 是否返回true禁止其他如table的分页器关联操作 */,
onButtonClick /** 有其他额外button按钮时触发的操作 */,
form: { getFieldDecorator, validateFields, setFieldsValue, resetFields }
}) => {
if (!searchList) {
searchList = [];
}
/** 搜索 */
const handleSearch = () => {
validateFields((err, fieldsValue) => {
// console.log(err);
// console.log(fieldsValue);
if (!err) {
stopPagination && stopPagination(false);
} else {
message.destroy();
message.error("搜索条件有误", 1.5);
stopPagination && stopPagination(true);
}
onSearch && onSearch(fieldsValue);
});
};
/** 获取时间段 */
const getRangeTime = (key, range, permission) => {
const time = [range.startTime, range.endTime, permission];
const fields = {
[key]: time
};
setFieldsValue(fields);
range.startTime && range.endTime && autoSearch && handleSearch();
};
/** datePicer衍生器onchange */
const dateChange = (mo, str) => {
onDateChange && onDateChange([str, mo]);
autoSearch && handleSearch();
};
return (
);
};
Search.propTypes = {};
export const SearchForm = Form.create({
name: "SearchForm",
// onFieldsChange(props, changedFields) {
/** 有多少个item会执行多少次 */
// props.onChange && props.onChange(changedFields);
// },
// mapPropsToFields(props) {
// // 对props做处理
// console.log(props);
// },
onValuesChange(props, values, e) {
/** 只会执行一次 */
props.onChange && props.onChange(values);
}
})(Search);