1.Menu
jsx
<Box sx={{ flexGrow: 0 }}>
<Tooltip title='Open settings'>
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
<Avatar
sx={{
bgcolor: "#f4d35e",
color: "#023047",
fontWeight: "bold",
cursor: "pointer",
}}>
{initials.toUpperCase()}
</Avatar>
</IconButton>
</Tooltip>
<Menu
sx={{ mt: "45px" }}
anchorEl={anchorElUser}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
keepMounted
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}>
{settings.map((setting) => (
<MenuItem key={setting}>
<Typography sx={{ textAlign: "center" }}>{setting}</Typography>
</MenuItem>
))}
</Menu>
</Box>
为什么 Menu
组件在激活时,点击其他地方可以关闭?
这是由于 Material-UI
的 Menu
组件默认会监听 全局的点击事件,当点击 非 Menu
内部区域 时,自动关闭 Menu
。
背后的原理
Menu
组件实际上是一个 基于 Popover
组件 实现的弹出菜单,它的关闭逻辑依赖于 点击外部区域的事件监听(ClickAwayListener),主要工作方式如下:
1. 监听全局点击事件
当 open={true}
时,Menu
组件会:
- 监听全局点击事件
- 判断 点击的目标元素是否在
Menu
内部 - 如果不在
Menu
内部,就关闭Menu
这就是为什么当 Menu
打开时,你点击任何 菜单外的区域,它都会自动关闭。
2. 关键的 onClose
触发机制
在 Menu
组件里:
jsx
<Menu
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu} // 关键
>
open={Boolean(anchorElUser)}
让Menu
处于打开状态。onClose={handleCloseUserMenu}
监听ClickAway
事件(点击外部区域时调用)。- 当你点击菜单外部,Material-UI 会自动触发
onClose
事件,执行handleCloseUserMenu
方法,让anchorElUser
变为null
,从而关闭Menu
。