需求分析
首先 我们需要实现一个带有搜索功能的搜索框 本次只实现两种框的搜索功能 一种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: `${item.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: `${item.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: `${item.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); }, []);