Ant 设计响应式 NavBar

Posted

技术标签:

【中文标题】Ant 设计响应式 NavBar【英文标题】:Ant design responsive NavBar 【发布时间】:2018-08-02 11:47:07 【问题描述】:

我正在使用 AntD,认为这对于一个通用和标准的响应式导航栏来说是一种简单快捷的设置,但结果证明它默认没有响应:

如您所见,它被压扁了。

代码如下:

<Menu
                        theme="dark"
                        mode="horizontal"
                        defaultSelectedKeys=["1"]
                        style= lineHeight: '64px' 
                        breakpoint="lg"
                        collapsedWidth="0"
                    >
                                <Menu.Item key="1">nav 1</Menu.Item>
                                <Menu.Item key="2">nav 2</Menu.Item>
                                <Menu.Item key="3">nav 3</Menu.Item>
                                <Menu.Item key="4"><Icon spin=true type="plus-circle" className="publish-btn" /></Menu.Item>
                                <Menu.Item key="5"><Icon spin=true type="login" className="loggin-btn" /></Menu.Item>
                    </Menu>

所以我再次阅读了文档,并认为我必须在菜单中使用 Grid 才能使其响应。但是,它给我带来了错误:

代码如下:

<Menu
                        theme="dark"
                        mode="horizontal"
                        defaultSelectedKeys=["1"]
                        style= lineHeight: '64px' 
                        breakpoint="lg"
                        collapsedWidth="0"
                    >

                        <Row key="1" gutter=16>
                            <Col span=3 key="1">
                                <Menu.Item key="1">nav 1</Menu.Item>
                            </Col>
                            <Col span=3 key="2">
                                <Menu.Item key="2">nav 2</Menu.Item>
                            </Col>
                            <Col span=3 key="3">
                                <Menu.Item key="3">nav 3</Menu.Item>
                            </Col>
                            <Col span=3 offset=9 key="4">
                                <Menu.Item key="4"><Icon spin=true type="plus-circle" className="publish-btn" /></Menu.Item>
                            </Col>
                            <Col span=3 key="5">
                                <Menu.Item key="5"><Icon type="login" className="loggin-btn" /></Menu.Item>
                            </Col>
                        </Row>
                    </Menu>

更新

让我澄清一下。我不想要侧边栏(因为在我的情况下它是一个小网站,页面不多)。我想要的只是在重新调整 Menu.Items 的大小时有一个顶部 NavBar。Items 可以折叠并变成一个汉堡包图标。另外,我需要右侧的 2 个 menu.items。

【问题讨论】:

【参考方案1】:

首先澄清一下:antd 文档所说的“响应式”(在文档中的 this example 中)是指不是导航栏项目重排,而是 侧边栏 折叠成一个较小的菜单或随着汉堡触发按钮的出现而消失。

第二:混合菜单和行/列是一个坏主意。发生错误是因为 Menu.Item 期望成为 Menu 的直接子元素,并且您通过 Row/Col 使其成为孙子元素,而它们没有传递相同的道具。

如您在说明中所述,AntD 不支持您的要求。我的一个基于 AntD 的网站的工作方式与您正在寻找的类似。我在该站点上所做的是呈现两组菜单,一组用于桌面导航栏,一组用于带有汉堡的小屏幕侧边栏,然后使用 CSS 媒体查询在 @screen-sm 断点的每一侧隐藏一组。

【讨论】:

您好贾斯珀,感谢您的回复。让我澄清一下自己。我不想要侧边栏(因为在我的情况下它是一个小网站,页面不多)。我想要的只是在重新调整 Menu.Items 的大小时有一个顶部 NavBar。Items 可以折叠并变成一个汉堡包图标。另外,我需要右侧的 2 个 menu.items。 我们是否有一个道具可以让 Menu.Items 折叠并变成汉堡图标? @JesperWe 感谢您的回复。你使用反应吗?您能否分享您在答案中描述的实现?【参考方案2】:

不久前我也在寻找这样的功能,并且 为了让 Ant Menu 响应式,我编写了一个简单的 React 组件。

此组件接受 Ant 菜单标记作为道具,并根据视口宽度有条件地呈现菜单,或者按原样(对于桌面),或者在将包装传递的菜单标记(对于移动)的 Popover 组件中。

我将包含屏幕截图,说明当视口足够窄以仅渲染汉堡图标时它的外观。

您可以找到带有工作示例 here 的 Github 存储库。

希望对你有帮助。

【讨论】:

感谢 Tomas,感谢您在这里所做的出色工作。只是一个问题,如果我们必须编写自己的代码,即使是为了这样一个简单的目的和等效的 UI 框架,例如Bootstrap 已经实现了,为什么还要使用 Ant Design?当我发现 AntDesign 的 NavBar 不是事件响应式时,这就是对 Ant Design 的感觉。 你说得对,Franva,虽然 Ant Design 中仍然缺少这个特殊功能,但其他 UI 框架中仍然缺少太多很棒的功能。我想说这总是关于妥协,对你的项目有用的东西不一定对另一个有用。举个例子,让我们比较一下 Ant Design 和 React Bootstrap 中的 Table 组件——Ant Design 中的 Table 组件与 Bootstrap 中的相比具有更多的功能和选项。我敢肯定,我提出的解决方案只是一个临时的,而且迟早或稍后响应式 Meni 将成为 Ant Design 的一部分 :) 同意 :) 希望不会花太长时间。【参考方案3】:

我在决定为一个项目选择 Ant 设计时正在考虑这个问题。响应式导航栏是常见的场景,但我想知道为什么 Ant Design 中没有这样的东西? 然后我在 repo 中搜索问题,发现 Ant Design Mobile 作为对问题的评论。

他们有一个单独的移动设备包。在 Ant Design Mobile 中,web components 有单独的部分。在该部分中,您可以找到适用于移动设备汉堡图标的Menu 组件。

希望这对未来的读者有所帮助。

【讨论】:

【参考方案4】:

对于响应行为,请使用 antd 的 Menu 组件中的“overflowedIndicator”属性。您可以选择菜单折叠时显示的任何 antd 图标。 使用 antd 的 Grid 能力 (Col xl,lg,md,sm,xs) 属性控制菜单何时折叠。

请查看下面的示例以获得简单的响应式导航栏:

import React from 'react';
import  Row, Col, Typography, Layout, Menu  from 'antd';
import  MenuOutlined  from '@ant-design/icons';

const  Header, Content  = Layout;
const  Title  = Typography;

export interface NavBarProps 
    selectedPage: string;
    children: React.ReactNode;


export const NavBar: React.FC<NavBarProps> = (props: NavBarProps) => 

const gotoPage = (page: string) => 
  //GO TO MENU ITEM PAGE
;

return (
<Row justify='center'>
  <Col xl=24 lg=24 md=24 sm=24 xs=24>
    <Header className='header-fixed'>
      <Row>
        <Col xl=12 lg=12 md=12 sm=20 xs=20>
          <Title id='title-button' level=4>
            <a onClick=() => gotoPage('')>My App</a>
          </Title>
        </Col>
        <Col xl=12 lg=12 md=12 sm=4 xs=4>
          <Menu
            theme='dark'
            mode='horizontal'
            defaultSelectedKeys=["item1"]
            overflowedIndicator=<MenuOutlined />
          >
            <Menu.Item
              key="item1"
              onClick=() => gotoPage("item1")
            >
              item1
            </Menu.Item>
            <Menu.Item
              key="item2"
              onClick=() => gotoPage("item2")
            >
              item2
            </Menu.Item>
            <Menu.Item
              key="item3"
              onClick=() => gotoPage("item3")
            >
              item3
            </Menu.Item>
          </Menu>
        </Col>
      </Row>
    </Header>
    <Content>props.children</Content>
  </Col>
</Row>
);
;

CSS:

.header-fixed 
  h4 
      margin-top: 15px;
      margin-bottom: 20px;
  

然后使用组件如下:

<NavBar selectedPage=''>
  <YourPageComponent />
</NavBar>

【讨论】:

看起来很有希望。

以上是关于Ant 设计响应式 NavBar的主要内容,如果未能解决你的问题,请参考以下文章

html Navbar响应式Bootstrap合理

响应式菜单(bootstrap)

bootstrap响应式导航条规则

如何使 Ant Design 表响应式

bootstrap 3 响应式巨型菜单

如何使用 vuetify 制作移动响应式导航栏