Happy New Year!

React实现简单的SearchBox搜索框组件

实现效果:

 

 React实现搜索组件,基于antd。

index.js文件

import React, { useState, useEffect } from 'react';
import { Menu, Dropdown, Input } from 'antd'; // 引入antd需要用到的组件

// 定义styles样式
import {
    Container,
    DropdownContainer,
    InputContainer,
    SearchContainer,
    ArrowContainer,
    DropdownContent,
} from './styles';

const PLACEHOLDER = '请输入关键词';

// 定义list列表类型
type List = {
    id: number | string,
    value: string,
};

// 定义props传输的参数类型
type SearchProps = {
    lists: Array<List>,
    backgroundColor: string,
    hasDropdown: boolean,
    trigger: string,
    activeId: string,
    size: string,
    hasBorder: boolean,
    placeholder: string,
    onClick: Function,
    onClickSearch: Function,
};

// 定义searchbox组件
const SearchBox = ({
    lists = [],
    trigger = 'click',
    backgroundColor = 'white',
    size = 'lg',
    activeId,
    hasBorder = false,
    hasDropdown = true,
    placeholder = PLACEHOLDER,
    onClickSearch = () => {},
    onClick = () => {},
}: SearchProps) => {
    const newProps = { backgroundColor, size, hasDropdown, hasBorder }; // 定义新对象
    const [currentId, setCurrentId] = useState(activeId); // 选择下拉active
    const [inputVal, setInputVal] = useState(''); // input输入内容
    const activeItem: List =
        lists &&
        lists.length > 0 &&
        lists.find(({ id }) => id === (currentId || lists[0].id));

    // 点击下拉方法
    /* istanbul ignore next */
    const handleMenuClick = e => {
        setCurrentId(e.key);
        onClick(null, e.key);
    };

    // 设置默认选中下拉状态
    useEffect(() => {
        if (!currentId && lists.length > 0) {
            setCurrentId(lists[0].id);
        }
    }, [currentId, lists]);

    // 下拉菜单列表
    const menu = () => {
        return (
            <Menu onClick={handleMenuClick}>
                {lists.map(({ id, value }) => {
                    return <Menu.Item key={id}>{value}</Menu.Item>;
                })}
            </Menu>
        );
    };

    // 输入框输入
    const onChange = e => {
        setInputVal(e.target.value);
    };

    // 搜索方法
    const search = () => {
        const item = {
            typeId: currentId,
            searchKey: inputVal,
        };
        if (onClickSearch) {
            onClickSearch(item);
        }
    };

    // 回车键执行搜索
    const onKeyDown = e => {
        /* istanbul ignore next */
        if (e.keyCode === 13) {
            search();
        }
    };
    
    // 搜索框结构
    return (
        <Container {...newProps}>
            {hasDropdown && lists.length > 0 && (
                <DropdownContainer>
                    <Dropdown overlay={menu} placement="topLeft" trigger={trigger}>
                        <DropdownContent>
                            <span>{activeItem.value}</span>
                            <ArrowContainer>
                                <img
                                    alt="downArrow"
                                    src="/next_static/svg-icons/KnowledgeMap/downArrow.svg"
                                />
                            </ArrowContainer>
                        </DropdownContent>
                    </Dropdown>
                </DropdownContainer>
            )}
            <InputContainer>
                <Input
                    placeholder={placeholder}
                    allowClear
                    value={inputVal}
                    onChange={onChange}
                    onKeyDown={onKeyDown}
                />
            </InputContainer>
            <SearchContainer onClick={search}>
                <img alt="search" src="/next_static/svg-icons/KnowledgeMap/search.svg" />
            </SearchContainer>
        </Container>
    );
};

export default SearchBox;

  

styles.js文件(css样式)

import styled, { css } from 'styled-components';
import Color, { searchbox } from '/components/style/colors'; // 封装颜色库,你可以输入色值
import FlexView from '../flexview'; // 封装flex布局组件,你可以自己手写flex布局

export const Container = styled(FlexView)`
    width: 100%;
    background-color: ${props => props.backgroundColor};
    border-radius: 50px;
    padding: 9px 18px 9px;
    box-sizing: border-box;
    ${({ size }) =>
        size === 'sm' &&
        css`
            padding: 3px 18px 3px 9px;
        `}
    ${({ hasDropdown }) =>
        hasDropdown &&
        css`
            padding-left: 20px;
        `}
    ${({ hasBorder }) =>
        hasBorder &&
        css`
            border: 1px solid ${searchbox.borderColor};
        `}
`;
export const DropdownContainer = styled(FlexView)`
    border-right: 1px solid ${searchbox.gray};
    white-space: nowrap;
    padding-right: 15px;
    margin-right: 5px;
    color: ${Color.gray2};
    cursor: pointer;
`;
export const InputContainer = styled.div`
    width: 100%;
    > span {
        background-color: transparent;
        border: none;
        outline: none;
        &:focus,
        &.ant-input-affix-wrapper:hover,
        &.ant-input-affix-wrapper-focused {
            border-color: transparent;
            box-shadow: none;
        }
        input {
            background-color: transparent;
            border: none;
        }
    }
`;
export const SearchContainer = styled(FlexView)`
    cursor: pointer;
`;
export const DropdownContent = styled(FlexView)`
    overflow: hidden;
`;
export const ArrowContainer = styled.div`
    overflow: hidden;
    margin-left: 15px;
`;

  

调用组件

// 选择类型
const searchType = [
    {
        id: 'all',
        value: '全部',
    },
    {
        id: 'kg',
        value: 'KG',
    },
    {
        id: 'algorithm',
        value: 'AI算法',
    },
    {
        id: 'analysis',
        value: '分析模型',
    },
];

<SearchBox
    backgroundColor='#F7F7F7' // 自定义背景色
    placeholder='请输入关键词' // 输入框提示
    hasDropdown // 是否显示下拉搜索类型
    lists={searchType} // 下拉搜索类型列表
    activeId='all' // 默认下拉类型
    trigger='click' // 触发方式 'click' or 'hover'
    onClick={() => {}} // 点击菜单执行方法
    onClickSearch={() => {}} // 点击搜索按钮执行
    size='lg' // 大小 lg or sm
    hasBorder={false} // 是否有边框
/>

  这样就实现了一个简单的react搜索组件。

posted @ 2020-09-16 13:11  一只看夕阳的猫  阅读(6139)  评论(0编辑  收藏  举报
返回顶部小火箭
世界很公平,想要最好,就一定得付出!
x
博客主页