📅  最后修改于: 2023-12-03 15:21:26.633000             🧑  作者: Mango
在编写 UI 界面时,下拉菜单是经常使用的一个控件。在用户点击下拉菜单时,通常会弹出一个菜单列表供用户选择。
本文将介绍如何实现一次只打开一个下拉菜单的功能,即当用户点击一个下拉菜单时,其他所有下拉菜单都将关闭,只打开当前点击的下拉菜单。
实现此功能的思路比较简单,即在点击下拉菜单时,遍历所有下拉菜单,将其它下拉菜单关闭,只打开当前点击的下拉菜单。
为了更好地实现此功能,我们可以将每个下拉菜单封装成一个组件,并将每个组件都设置一个唯一的 ID。当用户点击某个下拉菜单时,组件将向父组件发送一个事件,通知父组件关闭其它所有下拉菜单,并打开当前点击的下拉菜单。
父组件接收到事件后,遍历所有下拉菜单组件,将其它组件关闭。
以下为组件结构图:
Parent Component
└─ Dropdown Component 1
└─ Dropdown Component 2
└─ ...
我们以 React 为例来实现这个功能。
首先,我们创建一个父组件 Parent
,用于包含所有的下拉菜单组件:
import React, { useState } from 'react';
import Dropdown from './Dropdown';
function Parent() {
const [activeId, setActiveId] = useState(null);
function handleDropdownClick(id) {
setActiveId(id);
}
return (
<div>
<Dropdown id="dropdown1" active={activeId === 'dropdown1'} onClick={() => handleDropdownClick('dropdown1')} />
<Dropdown id="dropdown2" active={activeId === 'dropdown2'} onClick={() => handleDropdownClick('dropdown2')} />
{/* ... */}
</div>
);
}
export default Parent;
从上面的代码可以看出,我们在 Parent
组件中定义了一个 activeId
状态来记录当前激活的下拉菜单组件的 ID。接着,我们定义了一个 handleDropdownClick
函数来处理下拉菜单的点击事件,并将点击的菜单组件 ID 赋值给 activeId
状态。
接下来,我们创建一个 Dropdown
子组件,用于显示下拉菜单:
import React, { forwardRef } from 'react';
import PropTypes from 'prop-types';
const Dropdown = forwardRef(({ id, active, onClick }, ref) => {
return (
<div
ref={ref}
className="dropdown"
style={{
display: active ? 'block' : 'none',
}}
onClick={onClick}
>
{/* 下拉菜单内容 */}
</div>
);
});
Dropdown.propTypes = {
id: PropTypes.string.isRequired,
active: PropTypes.bool.isRequired,
onClick: PropTypes.func.isRequired,
};
export default Dropdown;
在上面的代码中,我们使用了 React Hooks 中的 forwardRef
函数将 Dropdown
组件包装一下。
我们的 Dropdown
组件接收了以下 3 个属性:
id
:下拉菜单的唯一 IDactive
:下拉菜单是否激活onClick
:下拉菜单点击事件接着,在 return
中,我们根据 active
属性的值来判断下拉菜单是否显示。
下面是 Dropdown
组件的使用方式:
<Dropdown id="dropdown1" active={activeId === 'dropdown1'} onClick={() => handleDropdownClick('dropdown1')} />
最后,我们定义 handleDropdownClick
函数,用于遍历所有下拉菜单组件,将其它组件关闭:
function handleDropdownClick(id) {
setActiveId(id);
const dropdowns = document.querySelectorAll('.dropdown');
dropdowns.forEach((dropdown) => {
if (dropdown.id !== id) {
dropdown.style.display = 'none';
}
});
}
我们可以在 handleDropdownClick
函数中使用 querySelectorAll
方法查询所有下拉菜单,并使用 forEach
方法遍历这些下拉菜单。如果下拉菜单的 ID 不等于当前点击的菜单组件 ID,则将其状态调整为不激活。
通过以上实现,我们成功地实现了每次打开一个下拉菜单的功能。这种实现方式是比较简单且易懂的,适用于简单的应用场景。