AntDesign下,Select内嵌Menu标签,做一个多选下拉框,既可以搜索,还可以选择下拉项

话不多说,直接上效果和代码
效果图一:

效果图二:

bash 复制代码
renderAddStyleOption = (item: any) => {
   const { value } = this.props;
   const { currentSelectedOptionIds, currentStyleId } = this.state;
   const styleSettings = value?.styleSettings;

   const newStyleSettings = styleSettings && styleSettings.length ? styleSettings : [];
   if (item) {
       const hasSearchKeyword = find([...item.allOptions, ...item.options], {
           name: item.optionKeyword,
       });
       return (
           <div
               className="specs-settings-popover"
               onBlur={() => {
                   this.setState({
                       currentStyleId: undefined,
                   });
               }}
           >
               <div
                   onMouseDown={(e) => {
                       e.preventDefault();
                       return false;
                   }}
               >
                   <Select
                       style={{ width: '300px' }}
                       placeholder={language.getText('selectPlease')}
                       mode="multiple"
                       autoClearSearchValue
                       showSearch
                       filterOption={false}
                       onChange={(selectedValues: any) => {
                           this.setState({
                               currentSelectedOptionIds: selectedValues,
                           });
                       }}
                       value={currentSelectedOptionIds}
                       onSearch={(keyword: string) => {
                           this.onSearch(item.id, newStyleSettings, keyword);
                       }}
                       onFocus={() => {
                           this.onSearch(item.id, newStyleSettings);
                       }}
                       open={currentStyleId === item.id}
                       onDropdownVisibleChange={() => {
                           this.setState({
                               currentStyleId: item.id,
                           });
                       }}
                       dropdownRender={() => (
                           <Menu
                               className="select-menu"
                               onClick={async (e: any) => {
                                   this.selectedStyleOption(e.key, item.id);
                               }}
                           >
                               {!hasSearchKeyword && item.optionKeyword && (
                                   <Menu.Item
                                       key={item.optionKeyword}
                                       className="add-menu-item"
                                   >
                                       <Icon type="plus" style={{ marginRight: '5px' }} />
                                       {item.optionKeyword}
                                   </Menu.Item>
                               )}
                               {item.options &&
                                   item.options.map((attribute: any) => {
                                       return (
                                           <Menu.Item
                                               key={attribute.id}
                                               className="select-menu-item"
                                           >
                                               {attribute.name}
                                               {currentSelectedOptionIds.includes(
                                                   attribute.id + ''
                                               ) && (
                                                   <Icon
                                                       type="check"
                                                       style={{ marginLeft: '5px' }}
                                                   />
                                               )}
                                           </Menu.Item>
                                       );
                                   })}
                           </Menu>
                       )}
                   >
                       {item.options &&
                           item.options.map((attribute: any) => {
                               return (
                                   <Select.Option
                                       key={attribute.id}
                                       value={String(attribute.id)}
                                   >
                                       {attribute.name}
                                   </Select.Option>
                               );
                           })}
                   </Select>
               </div>
               <Button
                   className="popover-btn"
                   type="default"
                   onClick={() => {
                       this.toggleOptionPopover(item.id);
                   }}
               >
                   {language.getText('common.cancel')}
               </Button>
               <Button
                   className="popover-btn"
                   type="primary"
                   onClick={() => {
                       this.addStyleOption(item.id);
                   }}
               >
                   {language.getText('common.add')}
               </Button>
           </div>
       );
   } else {
       return null;
   }
};

直接说重点,时间问题,不单纯出简单代码为大家说明了

1.关于下拉项事件的加载,可以通过onSearch和onFocus
获取你们的数据源,其中onSearch会返回name也就是select输入框的关键字,可以与后端接口请求获取

2.为什么使用Menu?是发现在Select输入关键字,下拉项出现"新增关键字"选项时,即使不点也会默认选中第一项,而"新增关键字"还未加入数据库,id获取不到,因此使用了Menu来控制到底是不是用户手动点的,

(也有人想要这种简便操作,就是点击"新增关键字",移除select也仍然加入数据库这种交互的话,那直接用select无需嵌套Menu可做到。我的需求是必须是用户手动点击下拉项才可以添加到数据库,避免一些伪操作数据的产生,大家自行判断~)

3.使用Menu大家应该也会遇到其他的卡点,可以移步到我上次写的一个博客,里面有详细写遇到的问题~
https://blog.csdn.net/weixin_43517190/article/details/147008156?spm=1001.2014.3001.5501

相关推荐
星栈1 小时前
视频即代码,Remotion 能做什么、不能做什么
前端·音视频开发
广州华水科技2 小时前
单北斗GNSS位移监测系统的应用与技术解析
前端
用户47949283569152 小时前
从一句话或代码仓到可交互 HTML:开源 Agent 画图技能 Archify v3.2 实测与选型边界
前端·后端·面试
风骏时光牛马4 小时前
生成一个AI多模态标题,仅输出一条标题,无额外文字、问句、备选、配图、文案等任何附加内容,不需要其他的任务服务 只要标题。
前端
wangruofeng5 小时前
从 GIF 到 AVIF:网页图片格式演进与 2026 年选型指南
前端·架构
清晨Coding6 小时前
为什么用 React Developer Tools 查看组件树这么乱?
前端·react.js
鶴哥只手遮天6 小时前
《Electron 45.2.3 内核解剖》第 4 章 补丁体系:380 个补丁改了什么
前端·electron
FungLeo8 小时前
成为全栈·Vue 管理后台篇·分类树与标签管理:层级数据如何落到管理界面
前端·javascript·vue.js·分类树·naive ui·标签管理·前端数据结构
Lank_M12 小时前
白底都占八成,PNG 为何只在图表页赢过 JPG
前端
张一凡9312 小时前
给 Coding Agent 加一道"架构闸门":Jin 是如何做到"先审架构、再写代码、不漂移"的
前端·后端·agent