在做一些需求的时候,使用下拉框,发现单纯的Select标签满足不了,于是采用Menu处理下拉的选项,发现的问题一一举例,希望对大家有帮助,少踩坑❤️
记得整片文章看完呦~,坑不少
—————————————————————————————————
1.问题:antd Select 组件扩展菜单 dropdownRender 中的点击事件不能被正常触发,或者说偶尔可以触发
解决方案:Select外围包一层div,设置onMouseDown事件
<div
onMouseDown={(e) => {
e.preventDefault();
return false;
}}
>
<Select></Select>
</div>
马上第二个问题来了~
2.问题:onMouseDown设置完之后,发现可以正常点击了,但是点击完后下拉项弹层不能及时关闭
解决方案:尝试过很多种比如ref之类的blur事件,发现都没用。最后采用的是控制select的开关,设置一个state值为open,然后Select设置open和onDropdownVisibleChang,最下方有示例代码
3.还有一个问题,就是鼠标点击页面其他地方,选项弹层还是没消失,
解决方案:dev外层又套了一层
<div
onBlur={() => {
this.setState({
selectOpen: false,
});
}}
></div>
整体代码如下:
renderAddParameterGroupModal = () => {
const {
isOpenAddModal,
searchKeyword,
parameterGroupOptions,
chooseParameterGroupOption,
selectOpen,
} = this.state;
const parameterGroupOptionsHasSearchKeyword = searchKeyword
? filter(parameterGroupOptions, (p) => p.name.includes(searchKeyword)) || []
: parameterGroupOptions;
return (
<Modal
title=""
visible={isOpenAddModal}
onCancel={this.closeAddModal}
onOk={this.onAddParameterGroupOrParameter}
>
<div
onBlur={() => {
this.setState({
selectOpen: false,
});
}}
>
<div
onMouseDown={(e) => {
e.preventDefault();
return false;
}}
>
<Select
className={innerClassNames.selector}
placeholder={language.getText('selectPlease')}
value={chooseParameterGroupOption?.id}
autoClearSearchValue
showSearch
filterOption={false}
onSearch={(name?: string) => {
this.setState({
searchKeyword: name,
});
}}
open={selectOpen}
onDropdownVisibleChange={() => {
this.setState({
selectOpen: true,
});
}}
dropdownRender={() => (
<Menu
className={innerClassNames.menu}
onClick={async (e: any) => {
//this.selectedParameterGroupOptions(e.key); //指定选择后的方法,可忽略,自己玩吧,这是我的
this.setState({
selectOpen: false,
});
}}
>
{!parameterGroupOptionsHasSearchKeyword.length &&
searchKeyword && (
<Menu.Item
key={-1}
className={innerClassNames.menuItem}
style={{ color: '#4C91FF' }}
>
<Icon
type="plus"
style={{ marginRight: '5px' }}
/>
{language.getText('common.add')}
{searchKeyword}
</Menu.Item>
)}
{parameterGroupOptionsHasSearchKeyword &&
parameterGroupOptionsHasSearchKeyword.map((g) => {
return (
<Menu.Item
key={g.id}
className={innerClassNames.menuItem}
>
{g.name}
</Menu.Item>
);
})}
</Menu>
)}
>
{parameterGroupOptionsHasSearchKeyword &&
parameterGroupOptionsHasSearchKeyword.map((g) => {
return (
<Select.Option key={g.id} value={g.id}>
{g.name}
</Select.Option>
);
})}
</Select>
</div>
</div>
</Modal>
);
};
我做的这个功能满足的是
1.一个下拉框,可以直接选择下拉项
2.也可以通过输入名称,选择下拉项
3.如果数据没有的话,就展示新增,点击可直接新增并选中【代码没放,自己写吧,应该很简单,id为-1的时候走新增接口】
贴出来方便大家复制😄,自行查找关键代码吧~
——————————————————后续补充——————————————————
有人说,我的页面好多Select怎么办呢?我不想集合里每个对象都加一个state控制开关
那我给个建议就是:还是设置一个state,只不过设置的是一个id
handleDropdownVisibleChange = (index: number) => {
this.setState({ selectOpenIndex: index});
};
onResetSelectOpenIndex = () => {
this.setState({ selectOpenIndex: undefined });
};
有没有瞬间就觉得简单了呢~ 😄😄😄