【React工作记录七十七】React+hook+ts+ant design封装一个input和select搜索的组件

简介: React+hook+ts+ant design封装一个input和select搜索的组件

需求分析

首先 我们需要实现一个带有搜索功能的搜索框 本次只实现两种框的搜索功能 一种input 一种select

功能思维

image.png

第一步 初始版本

先写出一个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);
    }, []);

结果

image.png

相关文章
|
2月前
|
前端开发 JavaScript 网络架构
react对antd中Select组件二次封装
本文介绍了如何在React中对Ant Design(antd)的Select组件进行二次封装,包括创建MSelect组件、定义默认属性、渲染Select组件,并展示了如何使用Less进行样式定义和如何在项目中使用封装后的Select组件。
89 2
react对antd中Select组件二次封装
|
3月前
|
前端开发
React使用useRef ts 报错
【8月更文挑战第17天】
66 4
|
2月前
|
前端开发
React添加路径别名alias、接受props默认值、并二次封装antd中Modal组件与使用
本文介绍了在React项目中如何添加路径别名alias以简化模块引入路径,设置组件props的默认值,以及如何二次封装Ant Design的Modal组件。文章还提供了具体的代码示例,包括配置Webpack的alias、设置defaultProps以及封装Modal组件的步骤和方法。
67 1
React添加路径别名alias、接受props默认值、并二次封装antd中Modal组件与使用
|
2月前
|
前端开发
react动态生成input、select标签以及思路总结
本文介绍了在React中动态生成input和select标签的方法,包括准备数据结构、在组件挂载时动态添加状态、页面渲染以及输入处理,最后总结了实现思路。
36 1
react动态生成input、select标签以及思路总结
|
1月前
|
前端开发
react 封装防抖
react 封装防抖
32 4
|
2月前
|
资源调度 JavaScript 前端开发
使用vite+react+ts+Ant Design开发后台管理项目(二)
使用vite+react+ts+Ant Design开发后台管理项目(二)
|
2月前
封装react-antd-table组件参数以及方法如rowSelection、pageNum、pageSize、分页方法等等
文章介绍了如何封装React-Antd的Table组件,包括参数和方法,如行选择(rowSelection)、页码(pageNum)、页面大小(pageSize)、分页方法等,以简化在不同表格组件中的重复代码。
61 0
|
3月前
|
前端开发 C++
使用 Vite 创建 React+TS+SW 项目并整合 AntDesign 、Scss 等组件或插件
本文记录了如何使用Vite创建一个React+TypeScript+Service Workers(SW)项目,并整合AntDesign组件库和Scss等插件,包括项目的创建、配置问题解决、AntDesign和Scss的整合方法。
243 1
|
4月前
|
前端开发
Vue3 【仿 react 的 hook】封装 useTitle
Vue3 【仿 react 的 hook】封装 useTitle
49 0
|
4月前
|
前端开发 API
Vue3 【仿 react 的 hook】封装 useLocation
Vue3 【仿 react 的 hook】封装 useLocation
40 0