pro-components
pro-components copied to clipboard
轻量筛选(LightFilter)使用树型下拉框(ProFormTreeSelect)时, “小舌头”显示位置有问题,并且无法关闭🐛[BUG]
🐛 bug 描述
轻量筛选(LightFilter)使用树型下拉框(ProFormTreeSelect)时, “小舌头”显示位置有问题,并且无法关闭
📷 复现步骤
https://codesandbox.io/s/qing-liang-shai-xuan-dan-chu-kuang-dui-qi-fang-shi-forked-1lqumc?file=/App.tsx


TAutomatically replying with ChatGPT can be attempted, but it cannot be guaranteed to be completely accurate and may not fully address all issues. Please feel free to reply if you have any further questions or concerns. 此回复基于 ChatGPT 自动生成,可以尝试下方案,官方员会在一定时间后继续继续处理。
🌟 可能的解决方案
通过观察代码和现象,我们可以将此问题整理为以下两个点:
- “小舌头”显示位置有问题
- 无法关闭
1. “小舌头”显示位置有问题
这里的 “小舌头” 是指 antd 的 Popover 组件,它默认是在目标元素下方垂直居中。根据我们的代码,目标元素是一个树型下拉框,而这个下拉框是使用 antd 的 TreeSelect 组件进行构建的,也就是说,Popover 默认是以 TreeSelect 的底部作为定位基准,但实际上它应该以输入框作为定位基准。
这个问题可以通过传递一个 getPopupContainer 函数解决:
<ProFormTreeSelect
// ...
getPopupContainer={(triggerNode) => triggerNode.parentElement}
>
通过配置 getPopupContainer 函数,可以告诉 Popover 应该以哪个节点作为定位基准,这里我们使用输入框的父节点作为基准即可。
2. 无法关闭
这个问题是因为点击外部区域时,树型下拉框并没有关闭。我们可以使用 useClickAway 钩子函数,当用户点击外部区域时,手动关闭树型下拉框。
首先需要在函数组件中引入 useRef 和 useEffect:
import { useRef, useEffect } from 'react';
然后,在组件中创建一个 Ref:
const treeSelectRef = useRef<any>();
在 ProFormTreeSelect 组件上,添加一个 ref 属性:
<ProFormTreeSelect
// ...
ref={treeSelectRef}
>
最后,在组件中使用 useClickAway 钩子函数,在点击外部区域时,手动调用 TreeSelect 的 onDropdownVisibleChange 方法:
useClickAway(() => {
treeSelectRef.current?.onDropdownVisibleChange(false);
});
这样就可以解决无法关闭的问题了。
最终的代码片段如下所示:
import React, { useRef, useEffect } from 'react';
import { LightFilter, ProFormTreeSelect } from '@ant-design/pro-form';
import { useClickAway } from '@umijs/hooks';
const App = () => {
const treeSelectRef = useRef<any>();
useClickAway(() => {
treeSelectRef.current?.onDropdownVisibleChange(false);
});
return (
<LightFilter onFinish={() => {}}>
<ProFormTreeSelect
name="category"
label="分类"
fieldProps={{
treeDefaultExpandAll: true,
treeData: [
{
key: '1',
title: '家用电器',
children: [
{
key: '1-1',
title: '厨房电器',
children: [
{
key: '1-1-1',
title: '电饭煲',
},
{
key: '1-1-2',
title: '电磁炉',
},
],
},
{
key: '1-2',
title: '生活电器',
children: [
{
key: '1-2-1',
title: '加湿器',
},
{
key: '1-2-2',
title: '空气净化器',
},
],
},
],
},
],
}}
getPopupContainer={(triggerNode) => triggerNode.parentElement}
ref={treeSelectRef}
/>
</LightFilter>
);
};
export default App;
📚 相关文档
- Ant Design Pro 站点: https://pro.ant.design/components/tree-select-cn/
- Ant Design 官方文档:https://ant.design/components/popover-cn/
修复啦,重新更新一下