需求分析
首先 我们需要实现一个带有搜索功能的搜索框 本次只实现两种框的搜索功能 一种input 一种select
功能思维
第一步 初始版本
先写出一个input和一个render 还有两个按钮
<Form.Item
label="测试数据"
key="1"
name="测试数据"
rules={xxx}
style={xxx}
>
{true ? <Select/> : <Input />}
</Form.Item>
<Form.Item>
<Button htmlType="submit">查询</Button>
</Form.Item>
<Form.Item>
<Button htmlType="reset" onClick={reset}>
重置
</Button>
</Form.Item>
开始升级版本(动态渲染搜索框)
接下来可以将搜索的数据改为动态渲染 因为按钮可以固定了 值从父级传入
{props.formList.map((item: SearchFormItem) => (
<Form.Item
label={props.showLabel !== false && item.label ? item.label : ''}
key={item.name}
name={item.name}
rules={item.rules}
style={{ width: `px` }}
>
{item.render ? item.render : <Input placeholder={item.placeholder} />}
</Form.Item>
))}
继续升级(方法通过子传父)
function SearchForm(props: SearchFormProps) {
const [form] = Form.useForm();
const reset = () => {
form.resetFields();
props.onSearch({});
};
const onSearch = () => {
form.validateFields().then(res => {
props.onSearch(res);
});
};
return (
<Form className="layout__search" form={form} layout="inline" onFinish={onSearch}>
{props.formList.map((item: SearchFormItem) => (
<Form.Item
label={props.showLabel !== false && item.label ? item.label : ''}
key={item.name}
name={item.name}
rules={item.rules}
style={{ width: `px` }}
>
{item.render ? item.render : <Input placeholder={item.placeholder} />}
</Form.Item>
))}
<Form.Item>
<Button htmlType="submit">查询</Button>
</Form.Item>
<Form.Item>
<Button htmlType="reset" onClick={reset}>
重置
</Button>
</Form.Item>
{
props.actions.map((action: SearchFormAction, index: number) => (
<Form.Item key={action.name}>
<Button type={action.type} onClick={() => props.onClick(index)}>
{action.name}
</Button>
</Form.Item>
))
}
</Form >
);
}
继续升级(ts限定数据类型)
import React, { memo } from 'react';
import { Button, Input, Form } from 'antd';
import { ButtonType } from 'antd/es/button/button';
import './index.less';
export interface SearchFormAction {
name: string;
type?: ButtonType;
}
export interface SearchFormItem {
name: string;
label: string;
placeholder?: string;
rules?: object[];
render?: React.ReactElement;
width?: any
}
interface SearchFormProps {
formList: SearchFormItem[];
onSearch: (values: any) => void;
actions: SearchFormAction[];
onClick: (index: number) => void;
showLabel?: boolean;
width?: any
}
function SearchForm(props: SearchFormProps) {
const [form] = Form.useForm();
const reset = () => {
form.resetFields();
props.onSearch({});
};
const onSearch = () => {
form.validateFields().then(res => {
props.onSearch(res);
});
};
return (
<Form className="layout__search" form={form} layout="inline" onFinish={onSearch}>
{props.formList.map((item: SearchFormItem) => (
<Form.Item
label={props.showLabel !== false && item.label ? item.label : ''}
key={item.name}
name={item.name}
rules={item.rules}
style={{ width: `px` }}
>
{item.render ? item.render : <Input placeholder={item.placeholder} />}
</Form.Item>
))}
<Form.Item>
<Button htmlType="submit">查询</Button>
</Form.Item>
<Form.Item>
<Button htmlType="reset" onClick={reset}>
重置
</Button>
</Form.Item>
{
props.actions.map((action: SearchFormAction, index: number) => (
<Form.Item key={action.name}>
<Button type={action.type} onClick={() => props.onClick(index)}>
{action.name}
</Button>
</Form.Item>
))
}
</Form >
);
}
export default memo(SearchForm);
看看父组件的使用
<Card>
<SearchForm
formList={formList}
actions={actions}
onSearch={onSearch}
onClick={onAddMenu}
showLabel={true}
></SearchForm>
</Card>
formList搜索表单值
const formList = useMemo<SearchFormItem[]>(
() => [
{
width: 280,
name: 'factoryId',
placeholder: '请选择所属工厂',
label: '所属工厂',
render: (
<Select
style={{ width: '100%' }}
placeholder="请选择所属工厂"
optionFilterProp="children"
>
{factoryDataList && factoryDataList.map((item: any) => (
<Option value={item.id}>{item.name}</Option>
))}
</Select>
)
},
],
[],
);
actions按钮值
const actions = useMemo<SearchFormAction[]>(
() => [
{
name: '新建',
type: 'primary',
},
],
[],
);
onSearch子传父方法值
const onSearch = useCallback(
(params: MenuSearchParams) => {
initPageList(params);
},
[page],
);
onAddMenu 控制弹框开启的值
const onAddMenu = useCallback(() => {
setCurrentMenu(null);
setEditVisible(true);
}, []);