【问题标题】:How to make a dropdown menu open below the Appbar using Material-UI?如何使用 Material-UI 在 Appbar 下方打开下拉菜单?
【发布时间】:2018-06-17 21:05:09
【问题描述】:

我是 Material-UI 的新手,刚刚开始摆弄他们的 App bar with Menu example。切换菜单下拉菜单时,它会在 Appbar 本身上打开,而我希望它在 Navbar 下方打开。

从文档中,我了解到这可以使用 anchorEl 来完成,正如 here 所解释的那样。但是当我将这个实现到我的menu 组件时,什么也没有发生。什么是“正确的 Material-UI 方式”来处理这个问题?

class Header extends React.Component {
  state = {
    auth: true,
    anchorEl: null,
    anchorOriginVertical: 'bottom',
    anchorOriginHorizontal: 'right',
    transformOriginVertical: 'top',
    transformOriginHorizontal: 'right',
    anchorReference: 'anchorEl',
  };

  handleChange = (event, checked) => {
    this.setState({ auth: checked });
  };

  handleMenu = event => {
    this.setState({ anchorEl: event.currentTarget });
  };

  handleClose = () => {
    this.setState({ anchorEl: null });
  };

  render() {
    const { classes } = this.props;
    const { auth, anchorEl } = this.state;
    const open = Boolean(anchorEl);

    return (
      <div className={classes.root}>
        <AppBar position="static">
          <Toolbar>
            <Typography type="title" color="inherit" className={classes.flex}>
              Title
            </Typography>
            {auth && (
              <div>
                <IconButton
                  aria-owns={open ? 'menu-appbar' : null}
                  aria-haspopup="true"
                  onClick={this.handleMenu}
                  color="contrast"
                >
                  <AccountCircle />
                </IconButton>
                <Menu
                  id="menu-appbar"
                  anchorEl={anchorEl}
                  open={open}
                  onClose={this.handleClose}
                >
                  <MenuItem onClick={this.handleClose}>Profile</MenuItem>
                  <MenuItem onClick={this.handleClose}>My account</MenuItem>
                </Menu>
              </div>
            )}
          </Toolbar>
        </AppBar>
      </div>
    );
  }
}

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    我有一个类似的问题,我让它工作的方式是通过设置菜单本身的属性,如下所示:

      <Menu
        id="menu-appbar"
        anchorEl={anchorEl}
        getContentAnchorEl={null}
        anchorOrigin={{ vertical: "bottom", horizontal: "center" }}
        transformOrigin={{ vertical: "top", horizontal: "center" }}
        open={open}
        onClose={this.handleClose}
        className={props.classes.menu}
      >
    

    我必须输入getContentAnchorEl={null} 才能使垂直属性起作用,我最终从这个问题https://github.com/mui-org/material-ui/issues/7961 中学到了这一点。

    不确定在使用状态设置锚元素的属性时如何执行此操作,但也许这会让您入门。

    【讨论】:

    • 此解决方案在 2020 年 4 月仍然有效,但 MUI should be more explicit about it。还有@Emmy,您可以编辑问题并修复链接:)我刚刚为您提供了弹出窗口演示的fixed the link
    • getContentAnchorEl prop 为我工作。我在所需的锚点原点下方弹出了菜单。当对两个内联按钮使用两个菜单弹出框时会发生这种情况
    • 顶部获取按钮下方的菜单,我使用anchorOrigin={{ vertical: 'bottom',horizontal: 'left' }} transformOrigin={{ vertical: 'top', horizontal: 'left' }}
    • 非常感谢,我已经为这个问题苦苦挣扎了几个小时,直到我找到了这个答案!
    【解决方案2】:

    这是因为你没有定义锚点。

    Menu 属性——anchorEl,负责传递调用它的按钮的位置,不是这样说的,只是为了便于理解。

    这样,只要有点击,您就应该参考。我建议你使用反应钩子,它可以使组件干净。

    反应状态

    const [menuOpen, setMenuOpen] = useState(false)
    const [anchorEl, setAnchorEl] = useState(false)
    
    const handleClick = (event) => {
    const anchorEl = event.currentTarget
    this.setState({ ...this.state, menuOpen: !menuOpen , anchorEl })
    

    反应钩子

    const [menuOpen, setMenuOpen] = useState(false)
    const [anchorEl, setAnchorEl] = useState(false)
    
    const handleClick = (event) => {
    setAnchorEl(event.currentTarget)
    }
    

    渲染

    return (
     <Menu
       anchorEl={anchorEl}
       open={menuOpen}
       onClose={handleClick }              
     </Menu 
    )
    

    【讨论】:

    【解决方案3】:

    Matheus 回答有误,anchorEl 的类型不是布尔型,在 ReactHooks 中它需要是:

      const [menuOpen, setMenuOpen] = useState<boolean>(false);
      const [anchorEl, setAnchorEl] = useState()
    
      const recordButtonPosition = (event: any) => {
          setAnchorEl(event.currentTarget);
          setMenuOpen(true);
      }
    
      let closeMenu = () => {
          setMenuOpen(false);
      }
    
      return (
          <React.Fragment>
              <Button onClick={recordButtonPosition}>
                  OPEN MENU
              </Button>
              <Menu
                  anchorEl={anchorEl}
                  open={menuOpen}
                  onClose={closeMenu}>
                  <MenuItem onClick={closeMenu}> ExampleMenuItem </MenuItem> 
              </Menu>
          </React.Fragment>
      );
    

    【讨论】:

      【解决方案4】:

      这是我的解决方案,希望对某人有所帮助。

      <Menu
        open={this.state.openProps}
        anchorEl={this.state.anchorEl}
        onClose={onClose}
        className={classes.styles}
        disableAutoFocusItem
        PaperProps={{
          style: {
            left: '50%',
            transform: 'translateX(-77%) translateY(32%)',
          }
        }}
        MenuListProps={{
          style: {
            padding: 0,
          },
        }}
      >
      

      【讨论】:

      • 谢谢我尝试锚定但弹跳,这对我有用。
      【解决方案5】:

      所有这些东西对我都不起作用。所以我给按钮一个 id 并使用 javascript 把它放在菜单上:

      <IconButton id="btnPerfil" onClick={this.toggleMenuPerfilOpen}>
          <AccountCircle color="inherit" />
      </IconButton>
      <Menu
        anchorPosition={{
          vertical: 'top',
          horizontal: 'center'
        }}
        anchorEl={document.getElementById('btnPerfil')}
        keepMounted
        open={this.state.isMenuPerfilOpen}
        onClose={this.toggleMenuPerfilOpen}
      >...</Menu>
      

      【讨论】:

        【解决方案6】:

        一个简单的方法是使用 useRef 挂钩

        1. 创建引用
        2. 如果您想在您的情况下显示菜单,请插入您的 ref 一个 Div 或其他
        3. 在菜单的锚属性中插入 ref

        在此处输入代码

        const inputEl = useRef(null);
        <Mycomponent ref={inputEl}/>
        <Menu
          id="simple-menu"
          anchorEl={inputEl.current}
          keepMounted
          open={Boolean(anchorEl)}
          onClose={handleClose}
        >
        

        对我来说这是最简单的方法

        【讨论】:

          【解决方案7】:

          对我来说,我有跳跃效果的问题,第一次点击后..我不得不制作keepMounted={false}

          您可以通过在 devTool 中调整translateX(10px) translateY(50px) 来获得 x 和 y 值。

                                <div>
                                   <Menu
                                              id="simple-menu"
                                              anchorEl={anchorEl}
                                              keepMounted={false}
                                              open={Boolean(anchorEl)}
                                              onClose={this.handleClose}
                                              PaperProps={{
                                                  style: {
                                                      transform: 'translateX(10px) translateY(50px)',
                                                  }
                                              }}
                                          >
                                              <MenuItem onClick={this.handleClose}>My Account</MenuItem>
                                              <Divider variant="middle"/>
                                              <MenuItem onClick={this.handleClose}>Logout</MenuItem>
                                          </Menu>
                                      </div>

          【讨论】:

            【解决方案8】:

            在 New Material-ui 版本 5 中,我不明白为什么会发生这种奇怪的事情。但是当我在应用栏中创建一个单独的菜单组件时它可以工作。

            import * as React from 'react';
            import { useRouter } from 'next/router'
            import { Menu, IconButton, } from '@mui/material';
            import MenuItem from '@mui/material/MenuItem';
            import AccountCircle from '@mui/icons-material/AccountCircle';
            
            export default function AppBarMenu() {
                const router = useRouter()
                const [anchorEl, setAnchorEl] = React.useState(null);
                const open = Boolean(anchorEl);
                const handleClick = (event) => {
                    setAnchorEl(event.currentTarget);
                };
                const handleClose = () => {
                    setAnchorEl(null);
                };
                const handleLogout = () => {
                    localStorage.clear()
                    router.push('/auth/login')
                }
                return (
                    <>
                        <IconButton
                            id="basic-button"
                            size="large"
                            aria-controls="basic-menu"
                            aria-haspopup="true"
                            aria-expanded={open ? 'true' : undefined}
                            onClick={handleClick}
                        >
                            <AccountCircle sx={{ color: 'white' }} />
                        </IconButton>
                        <Menu
                            id="basic-menu"
                            anchorEl={anchorEl}
                            open={open}
                            onClose={handleClose}
                            MenuListProps={{
                                'aria-labelledby': 'basic-button',
                            }}
                        >
                            <MenuItem onClick={handleClose}>Profile</MenuItem>
                            <MenuItem onClick={handleClose}>My account</MenuItem>
                            <MenuItem onClick={handleLogout}>Logout</MenuItem>
                        </Menu>
                    </>
                );
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-06-23
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-01-25
              • 1970-01-01
              相关资源
              最近更新 更多