【问题标题】:Creating a navbar with Material-UI使用 Material-UI 创建导航栏
【发布时间】:2023-03-10 17:41:01
【问题描述】:

我正在尝试使用 Material-UI 创建一个简单的导航栏,看起来就像他们在 their site 上使用的导航栏。这是我编写的尝试复制它的代码:

import React from 'react'
import {AppBar, Tabs, Tab} from 'material-ui'

class Nav extends React.Component {
  render() {
    return (
      <AppBar title="My App">
        <Tabs>
          <Tab label="Item 1" />
          <Tab label="Item 2" />
          <Tab label="Item 3" />
          <Tab label="Item 4" />
        </Tabs>
      </AppBar>
    )
  }
}

React.render(<Nav />, document.body)

问题是,标签出现得很奇怪,点击标签没有任何效果。截图:

【问题讨论】:

    标签: javascript reactjs material-ui


    【解决方案1】:

    最新更新 [2018]

    Problem should be fixed in latest version.

    更新 #1 [2016]

    至少,the will is there - 并不是所有的希望都破灭了!

    原帖

    有同样的问题。

    原来是bug (#773)

    但你很幸运:This PR 提供了一个使用 CSS 的解决方案。它(有点)有效。截图如下:

    如您所见,它看起来有点难看,因此您可能需要继续摆弄 CSS 以使选项卡出现在正确的位置。

    注意:八个月前,the PR got rejected。显然,在AppBar 中显示Tabs 不是高优先级,所以,hackfix 解决方案就是你目前所拥有的!

    哦,使用预发布库的痛苦!

    【讨论】:

      【解决方案2】:

      我认为 Kabir 的回答是一个好的开始,我还将 &lt;Tabs&gt; 包装在 &lt;ToolbarGroup &gt; 中,因为 AppBar 是工具栏的子集。

      例如

      iconElementRight={<ToolbarGroup >{myTabs}</ToolbarGroup>}
      

      见:http://www.material-ui.com/#/components/toolbar

      【讨论】:

        【解决方案3】:

        聚会有点晚了,但一个对我有用的解决方案。仅供参考,这是一个带有 Rails 后端的 React/Redux 应用程序。

        import React, { Component } from 'react'
        import PropTypes from 'prop-types'
        import { Link } from 'react-router'
        import AppBar from 'material-ui/AppBar'
        import Drawer from 'material-ui/Drawer'
        import MenuItem from 'material-ui/MenuItem'
        import { getBasename } from '../config/environment'
        
        export default class Navbar extends Component {
          constructor(props) {
            super(props)
            this.state = {open: false}
            this.displayNavbar = this.displayNavbar.bind(this)
          }
        
          toggleDrawer = () => this.setState({ open: !this.state.open })
        
          authenticatedNavbar = () => {
            return (
              <div>
                <AppBar
                  iconElementRight={
                    <MenuItem
                      containerElement={<Link to={getBasename() + 'login'} />}
                      onTouchTap={() => {this.props.onLogoutClick()}}
                      primaryText="Logout"
                    />
                  }
                  onLeftIconButtonTouchTap={() => this.toggleDrawer()}
                  title="Your_app"
                />
                <Drawer
                  docked={false}
                  onRequestChange={(open) => this.setState({open})}
                  open={this.state.open}
                >
                  <MenuItem
                    containerElement={<Link to={getBasename() + 'home'} />}
                    onTouchTap={() => { this.toggleDrawer() }}
                    primaryText="Home"
                  />
                  <MenuItem
                    containerElement={<Link to={getBasename() + 'some_component'} />}
                    onTouchTap={() => { this.toggleDrawer() }}
                    primaryText="Some Component"
                  />
                </Drawer>
              </div>
            )
          }
        
          unauthenticatedNavbar = () => {
            return (
              <div>
                <AppBar
                  iconElementRight={
                    <MenuItem
                      containerElement={<Link to={getBasename() + 'login'} />}
                      primaryText="Login"
                    />
                  }
                  showMenuIconButton={false}
                  title="Your_app"
                />
              </div>
            )
          }
        

        然后是一些其他逻辑来根据用户的身份验证状态显示适当的 AppBar。

        我真的不认为选项卡是应用栏的一部分。 Material 规范将它们显示为辅助工具栏。

        【讨论】:

          【解决方案4】:

          你用过 react-tap-event-plugin 吗?根据https://github.com/callemall/material-ui/issues/288 需要。

          【讨论】:

            【解决方案5】:

            除了 CSS hack,我发现您可以使用 HTML Entities 作为 hack 来拆分标签文本。您可以将&amp;nbsp; 添加到选项卡标签的开头和结尾,然后您就有了空间。

            它使标签字符串变得丑陋,但如果您不太在意,它的工作效果很好,而且它还允许您添加任意数量的空格。

            这是更新后的代码:

            import React from 'react'
            import {AppBar, Tabs, Tab} from 'material-ui'
            
            class Nav extends React.Component {
              render() {
                return (
                  <AppBar title="My App">
                    <Tabs>
                      <Tab label="&nbsp;Item 1&nbsp;" />
                      <Tab label="&nbsp;Item 2&nbsp;" />
                      <Tab label="&nbsp;Item 3&nbsp;" />
                      <Tab label="&nbsp;Item 4&nbsp;" />
                    </Tabs>
                  </AppBar>
                )
              }
            }
            
            React.render(<Nav />, document.body)
            

            还有截图: Tabs with spaces

            【讨论】:

            • 使用&amp;nbsp; 在上面的 CSS hacks 上是不受欢迎的。 &amp;nbsp; 是为了让你免于撞墙,因为它不会以任何其他方式起作用。否则现在是 1994 年,没人在看。
            【解决方案6】:

            如果您想在AppBar 中水平显示多个项目,请将它们放在Toolbar 中,它会很好地显示。看到这个答案here知道原因。

            如果您想将导航栏推到右侧,请在Tabs 之前添加Box 并将flexGrow 设置为1。这将创建一个空的 div 元素。它之所以有效,是因为Toobar 容器使用了弹性布局。

            <AppBar position="static">
              <Toolbar>
                <IconButton size="large" edge="start" color="inherit" sx={{ mr: 2 }}>
                  <MenuIcon />
                </IconButton>
                <Box flexGrow={1} />
                <Tabs textColor="inherit">
                  <Tab label="One" />
                  <Tab label="Two" />
                  <Tab label="Three" />
                </Tabs>
              </Toolbar>
            </AppBar>
            

            完整示例

            export default function Demo() {
              const [value, setValue] = React.useState(0);
              const handleChange = (_, newValue) => setValue(newValue);
            
              return (
                <>
                  <AppBar position="static">
                    <Toolbar>
                      <IconButton size="large" edge="start" color="inherit" sx={{ mr: 2 }}>
                        <MenuIcon />
                      </IconButton>
                      <Typography
                        variant="h6"
                        noWrap
                        component="div"
                        sx={{ display: { xs: "none", sm: "block" } }}
                      >
                        MUI
                      </Typography>
                      <Box flexGrow={1} />
                      <Tabs value={value} onChange={handleChange} textColor="inherit">
                        <Tab label="One" />
                        <Tab label="Two" />
                        <Tab label="Three" />
                      </Tabs>
                    </Toolbar>
                  </AppBar>
                  <div index={value} onChangeIndex={setValue}>
                    <TabPanel value={value} index={0}>
                      Item One
                    </TabPanel>
                    <TabPanel value={value} index={1}>
                      Item Two
                    </TabPanel>
                    <TabPanel value={value} index={2}>
                      Item Three
                    </TabPanel>
                  </div>
                </>
              );
            }
            
            function TabPanel(props) {
              const { children, value, index, ...other } = props;
            
              return (
                <div role="tabpanel" hidden={value !== index} {...other}>
                  {value === index && (
                    <Box sx={{ p: 3 }}>
                      <Typography>{children}</Typography>
                    </Box>
                  )}
                </div>
              );
            }
            

            现场演示

            【讨论】:

              【解决方案7】:

              您是否阅读了 Material-UI documentation

              尝试将您的内容作为 iconElementRight 属性传递。

              即:

              render() {
                  var myTabs = (
                      <Tabs>
                          <Tab label="item 1" />
                          <Tab label="item 2" />
                      </Tabs>
                  );
                  return <AppBar title="My App" iconElementRight={myTabs} />
              }
              

              虽然,似乎只支持 3 种样式(如文档中的 3 个示例所示)。您可能需要对样式进行创意,因为它看起来不太灵活。

              PS 祝你好运,因为他们切换到内联样式和他们自己的自定义主题后,很难更改或集成其他非 mui 组件(我对此感到非常厌烦,我创建了一个使用 SASS 的分支https://www.npmjs.com/package/material-ui-with-sass)

              【讨论】:

              • 我试过这样做,结果是这样的:i.imgur.com/kJDEQe4.png 如果不做额外的样式和定制,真的没有办法像他们在网站上使用的那样创建一个导航栏吗?我认为一个简单的导航栏将是一个标准组件。
              • 看起来你已经很接近了,不是吗?为什么不直接设置标签的样式,给它们一些宽度和边距?我同意你的观点,你应该可以把标签放在那里,让它们不受应用栏的影响(看起来应该,就好像你把它们放在页面中间或其他地方一样)。 “梅路或高速公路”及其非标准主题/内联样式仍然让我抓狂。这样的事情不应该成为问题。无论如何,这就是我所拥有的。也许其他人会给出一个神奇的答案(但可能不会)。祝你好运。
              • 我很确定他希望标签和其他内容显示在导航栏下方,在页面主体中,而不是在导航栏中。
              猜你喜欢
              • 2018-12-21
              • 2021-03-16
              • 1970-01-01
              • 2017-12-19
              • 1970-01-01
              • 2022-11-29
              • 2021-07-11
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多