Skip to content

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-UIMenu 组件默认会监听 全局的点击事件,当点击 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