1. 程式人生 > 實用技巧 >React實現簡單的SearchBox搜尋框元件

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搜尋元件。