react+antd快捷菜单搜索组件:MenuSearch
一、MenuSearch/index.tsx
import React, { useState, useEffect } from 'react' import { Select } from 'antd' import { history } from 'umi' import styles from './index.less' import { SearchOutlined } from '@ant-design/icons' interface MenuSearchProps { routerOptions: Array<object> // 下拉框options routerList: Array<string> // pathname集合 } const MenuSearch: React.FC<MenuSearchProps> = (props: any) => { const { routerOptions, routerList } = props let { pathname, search } = history.location pathname = pathname + search const [currentPath, setcurrentPath] = useState<string | undefined>(undefined) const [isHide, setIsHide] = useState(true) // 是否隐藏搜索框 默认隐藏 useEffect(() => { const currentPath = routerList.includes(pathname) ? pathname : undefined setcurrentPath(currentPath) // 点击菜单栏,menuSearch中回显 }, [pathname, routerList]) return ( <div className={styles.menuSearch}> <SearchOutlined onClick={setIsHide.bind(this, !isHide)} /> <Select onChange={(pathname: string) => history.push(pathname)} showSearch optionFilterProp="label" placeholder="请搜索菜单名称" options={routerOptions} value={currentPath} className={isHide ? styles.isHide : null} onBlur={setIsHide.bind(this, true)} getPopupContainer={(triggerNode) => triggerNode.parentNode} /> </div> ) } export default MenuSearch
MenuSearch/index.less
.menuSearch { display: flex; align-items: center; :global { .ant-select { width: 200px; margin-right: 20px; margin-left: 10px; transition: all 0.5s; .ant-select-selector { border-radius: 4px; background-color: var(--theme-input-bk); } } } .isHide { width: 0; opacity: 0; // overflow: hidden; margin-right: 0; } }
二、使用
BasicLayout.tsx
import MenuSearch from './components/MenuSearch'
<MenuSearch routerOptions={routerOptions} routerList={routerList} />
三、数据结构
routerOptions
[ { "name": "监测台", "path": "/monitoringStation", "label": "监测台", "value": "/monitoringStation", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-gongzuotai" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "客户列表", "path": "/customer/customerList", "label": "客户列表", "value": "/customer/customerList", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "项目库", "path": "/crm/project", "label": "项目库", "value": "/crm/project", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "学校库", "path": "/crm/school", "label": "学校库", "value": "/crm/school", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "员工项目管理", "path": "/management/staffproject", "label": "员工项目管理", "value": "/management/staffproject", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "模板管理", "path": "/management/template", "label": "模板管理", "value": "/management/template", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "项目流程管理", "path": "/management/projectProcess", "label": "项目流程管理", "value": "/management/projectProcess", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "客户信任流程管理", "path": "/management/customerTrust?flowType=2", "label": "客户信任流程管理", "value": "/management/customerTrust?flowType=2", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "服务流程管理", "path": "/management/processOrderlySales", "label": "服务流程管理", "value": "/management/processOrderlySales", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "周计划维度管理", "path": "/management/weeklyPlan?flowType=3", "label": "周计划维度管理", "value": "/management/weeklyPlan?flowType=3", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "知识库设置", "path": "/management/knowledge", "label": "知识库设置", "value": "/management/knowledge", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "产品库设置", "path": "/management/product", "label": "产品库设置", "value": "/management/product", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "项目阶段设置", "path": "/management/projectStage", "label": "项目阶段设置", "value": "/management/projectStage", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "服务阶段设置", "path": "/management/projectPhase", "label": "服务阶段设置", "value": "/management/projectPhase", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "客户标签管理", "path": "/management/customerLabel", "label": "客户标签管理", "value": "/management/customerLabel", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "客户等级管理", "path": "/management/customerLevel", "label": "客户等级管理", "value": "/management/customerLevel", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "年度目标设置", "path": "/management/yearTargetSetting", "label": "年度目标设置", "value": "/management/yearTargetSetting", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "资料库", "path": "/application/database", "label": "资料库", "value": "/application/database", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "项目报", "path": "/application/projectreport", "label": "项目报", "value": "/application/projectreport", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "周计划", "path": "/application/weeklyPlan", "label": "周计划", "value": "/application/weeklyPlan", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "知识库", "path": "/application/knowledgeBase", "label": "知识库", "value": "/application/knowledgeBase", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon-xiaoxi" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "项目推进审核", "path": "/application/projectScheduleReview", "label": "项目推进审核", "value": "/application/projectScheduleReview", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "服务推进审核", "path": "/application/serverScheduleReview", "label": "服务推进审核", "value": "/application/serverScheduleReview", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "客户背调信息管理", "path": "/application/customerBackgroundInfoManage", "label": "客户背调信息管理", "value": "/application/customerBackgroundInfoManage", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "拜访计划", "path": "/application/visitPlan", "label": "拜访计划", "value": "/application/visitPlan", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "拜访反馈", "path": "/application/visitFeedback", "label": "拜访反馈", "value": "/application/visitFeedback", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "项目实时阶段", "path": "/dataCenter/projectRealTimePhase", "label": "项目实时阶段", "value": "/dataCenter/projectRealTimePhase", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "项目动态变化", "path": "/dataCenter/projectDynamicChange", "label": "项目动态变化", "value": "/dataCenter/projectDynamicChange", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "客户关系实时阶段", "path": "/dataCenter/customerRelationshipsRealTimePhase", "label": "客户关系实时阶段", "value": "/dataCenter/customerRelationshipsRealTimePhase", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "客户关系动态变化", "path": "/dataCenter/customerRelationshipsDynamicChange", "label": "客户关系动态变化", "value": "/dataCenter/customerRelationshipsDynamicChange", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "年度关键任务", "path": "/dataCenter/yearPivotalTask", "label": "年度关键任务", "value": "/dataCenter/yearPivotalTask", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "大区/公司", "path": "/dataCenter/regionCompany", "label": "大区/公司", "value": "/dataCenter/regionCompany", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "菜单管理", "path": "/setting/menuManage", "label": "菜单管理", "value": "/setting/menuManage", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "角色权限管理", "path": "/setting/roleJurisdiction", "label": "角色权限管理", "value": "/setting/roleJurisdiction", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "账号管理", "path": "/setting/account", "label": "账号管理", "value": "/setting/account", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "导入记录管理", "path": "/setting/importRecord", "label": "导入记录管理", "value": "/setting/importRecord", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "部门设置", "path": "/setting/department", "label": "部门设置", "value": "/setting/department", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] }, { "name": "临时团队管理", "path": "/setting/temporaryTeam", "label": "临时团队管理", "value": "/setting/temporaryTeam", "icon": { "type": "span", "key": null, "ref": null, "props": { "className": "iconfont icon-icon" }, "_owner": null, "_store": {} }, "children": [] } ]
routerList
[ "/monitoringStation", "/customer/customerList", "/crm/project", "/crm/school", "/management/staffproject", "/management/template", "/management/projectProcess", "/management/customerTrust?flowType=2", "/management/processOrderlySales", "/management/weeklyPlan?flowType=3", "/management/knowledge", "/management/product", "/management/projectStage", "/management/projectPhase", "/management/customerLabel", "/management/customerLevel", "/management/yearTargetSetting", "/application/database", "/application/projectreport", "/application/weeklyPlan", "/application/knowledgeBase", "/application/projectScheduleReview", "/application/serverScheduleReview", "/application/customerBackgroundInfoManage", "/application/visitPlan", "/application/visitFeedback", "/dataCenter/projectRealTimePhase", "/dataCenter/projectDynamicChange", "/dataCenter/customerRelationshipsRealTimePhase", "/dataCenter/customerRelationshipsDynamicChange", "/dataCenter/yearPivotalTask", "/dataCenter/regionCompany", "/setting/menuManage", "/setting/roleJurisdiction", "/setting/account", "/setting/importRecord", "/setting/department", "/setting/temporaryTeam", "/management/customerTrust", "/management/weeklyPlan" ]
四、效果
1、下拉框中支持搜索,点击菜单跳转至对应页面
2、点击左侧菜单栏,下拉框中回显当前菜单名称
3、点击放大镜icon展开下拉框,再次点击收起。下拉框失焦时收起下拉框
五、注意
1、根据路由拦截,如果路由中带参数(get形式),需要将?前路径截取下来,存到routerList中
{/* 路由拦截 【白名单】:pdf预览组件 */} {routerList.length ? ( // routerList.includes(pathname) || pathname.includes('/pdfPreview') ? ( routerList.some((item) => pathname.includes(item)) || pathname.includes('/pdfPreview') ? ( <Authorized authority={authorized!.authority} noMatch={noMatch}> {children} </Authorized> ) : pathname === '/' ? ( <Authorized authority={authorized!.authority} noMatch={noMatch}> {children} </Authorized> ) : ( noMatch ) ) : ( '' )}
2、当前菜单下有新增、编辑、详情等子路由,下拉框中是没有回显的,此时路由拦截的规则需要对应的修改