Material-ui: [MenuItem] 菜单项内的链接

创建于 2015-01-06  ·  43评论  ·  资料来源: mui-org/material-ui

嗨,我正在查看菜单项的当前实现,并注意到没有实际链接(意思是 html <a>标记)。 结果,例如,即使在导航栏中也没有实际的链接,并且通过 onclick 事件管理到其他页面的转换。

我认为拥有链接将是一种改进,尤其是考虑到服务器端呈现的页面。

你认为这是有道理的,还是你有具体的理由不朝这个方向发展?

最有用的评论

使用containerElement道具!

看:
http://stackoverflow.com/questions/32106513/material-ui-menu-using-routes/34507786#34507786

<MenuItem
  containerElement={<Link to="/profile" />}
  primaryText="Profile"
  leftIcon={
    <FontIcon className="material-icons">people</FontIcon>
  } />

所有43条评论

我也想知道这个。 我在我的应用程序中使用服务器端渲染,这是需要研究的。

使用具有href属性的锚元素也将提高可访问性并允许人们使用他们习惯的浏览器行为(例如 ⌘-单击以在新选项卡中打开)。

+1

+1

+1

+1

+1

+1

+1

@ecesena你认为这仍然是新的MenuItem组件的问题吗? 见这里MenuItem可以被<a>..</a>包围,不是吗?

这可以通过@shaurya947 的建议来实现。

我试图在我的 LeftNav 中使用MenuItems ,如下所示:

        let menuItems = (
            <div>
                <MenuItem primaryText="Doors"           leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} /></a>
                <MenuItem primaryText="Load"           leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
                <MenuItem primaryText="Notes"           leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
                <MenuItem primaryText="Alerts"          leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
                <MenuItem primaryText="Admin"           leftIcon={<FontIcon className="material-icons" color={GlobalStyles.default.activeColor}>home</FontIcon>} />
            </div>
        );

        return (
            <LeftNav
                ref="leftNav"
                docked={false}
                onChange={this._onLeftNavChange}
            >
                {menuItems}
            </LeftNav>
        )

<a>包裹在<MenuItem>标记周围会引发警告validateDOMNesting(...): <a> cannot appear as a descendant of <a>. See MainLayout > a > ... > MenuItem > ListItem > EnhancedButton > a"

如果你对输出进行 React 检查,你会得到以下结果。

<a href="/">
    <MenuItem..>
        <ListItem..>
            <div>
                <EnhancedButton..>
                    <a>
                        <TouchRipple ..>
                    </a>
                </EnhancedButton>
            </div>
        </ListItem>
    </MenuItem>
</a>

嵌套<a>元素是令人反感的。

<MenuItems>在 Button 声明中生成<a>元素。 MenuItem使用什么道具来填充生成的<EnhancedButton>的 href 属性?

使用 MenuItem 对象作为 LeftNav 的道具可以使链接正常工作,但我无法弄清楚如何以这种方式添加左/右图标。

IE:

let menuItems = [
         { route: '/load_areas/'+ this.state.area + '/doors', text: 'Doors' },
         { route: '/load_areas/'+ this.state.area + '/trailer_loads', text: 'Load' },
         { route: 'notes', text: 'Notes' },
         { route: 'alerts', text: 'Alerts' },
         { route: 'admin', text: 'Admin' }
         ];

<LeftNav
                ref="leftNav"
                docked={false}
                menuItems={menuItems}
                onChange={this._onLeftNavChange}
            />

这是一个单独的问题,请打开一个,以便我们标记它并将其添加到里程碑,tnx :grin:

使用containerElement道具!

看:
http://stackoverflow.com/questions/32106513/material-ui-menu-using-routes/34507786#34507786

<MenuItem
  containerElement={<Link to="/profile" />}
  primaryText="Profile"
  leftIcon={
    <FontIcon className="material-icons">people</FontIcon>
  } />

现在EnhancedButton的道具linkButton已被弃用。 当提供href属性时,不再需要 LinkBut​​ton。 它将在 v0.16.0 中删除。

例如:

<MenuItem primaryText="Primary Text" href="/your/link" />

href 重新加载页面。 如果我想使用反应路由器怎么样

@cezarneaga试试href="#/your/link"

<MenuItem
  containerElement={<Link to="/profile" />}
.../>

文档提到您还需要输入linkButton 。 如果您删除它,它可以正常工作。

@DaxChen我看到了您在 2016 年 12 月更新的 stackoverflow 答案(最近的哈哈),我想知道您是否知道这是否适用于抽屉中的 MenuItem? 我正在尝试以下操作,并且完全无法让 Link 与 MenuItem 一起工作,因为 containerElement 似乎什么也没做。

<Drawer
  docked={false}
  width={300}
  onRequestChange={this.closeDrawer}
  open={this.state.open}>
  <AppBar title="Title"
 />
  <MenuItem primaryText="home" containerElement={<Link to="/home" />} />
</Drawer>

containerElement 有效,但没有记录,所以我想这个线程现在必须作为官方文档。 谢谢!

@Faolain

真的很抱歉回复晚了...
我尝试使用create-react-app在干净的应用程序上编写代码,但一切似乎都正常?!
也许你配置的react-router不同,还是版本不同?

无论如何,这里有一个示例 RepoLive Demo Here

如果您仍然找不到问题的原因,您可以提供一个示例 repo 来重现吗?

上述解决方案均不适用于 Safari 和 iOS。 所以这就是我为react-router所做的工作

          <MenuItem
            onTouchTap={() => {
              this._yourMethod()
              browserHistory.push('/howItWorks')
            }}
            primaryText="Menu Link"
          />

@janzenz这个例子在你的浏览器中不起作用吗?

我在 macOS 上的 Safari 和 iOS 上的 Safari 中尝试过,它们都可以工作。 这不适合你吗?

尽管您的解决方法有效,但它可能会导致不良的 SEO,并且您将失去一些本机行为,例如链接预览和选项单击以在新选项卡中打开。

@DaxChen感谢您的见解。 我不确定我的问题是否与您的第一个链接有关。 我已经尝试了第二个,但是一旦我添加了onTouchTap道具, <Link />就不再起作用了。

@janzenz在之前的示例中添加了onTouchTap道具,它仍然有效。
不知道您的设置是否在某个地方有所不同...😢
您可以查看更新的代码,看看它是否适合您?

@DaxChen我看到您在material-ui版本中使用~0.16.0 。 您是否尝试过最新的~0.17.0并查看是否仍然没有问题?

@janzenz我使用的是旧版本,刚刚更新到最新的0.17.4并且它仍然有效!

触摸! 可能是我当时的设置。 感谢您确认@DaxChen,如果我发现了真正的问题,我会回到这个帖子。

@DaxChen ,我尝试了你给我的例子,但它失败了

Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in. Check the render method of `EnhancedButton`.
    at invariant (invariant.js:44)
    at ReactCompositeComponentWrapper.instantiateReactComponent [as _instantiateReactComponent] (instantiateReactComponent.js:74)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:367)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactDOMComponent.mountChildren (ReactMultiChild.js:238)
    at ReactDOMComponent._createInitialChildren (ReactDOMComponent.js:697)
    at ReactDOMComponent.mountComponent (ReactDOMComponent.js:516)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at ReactCompositeComponentWrapper.performInitialMount (ReactCompositeComponent.js:371)
    at ReactCompositeComponentWrapper.mountComponent (ReactCompositeComponent.js:258)
    at Object.mountComponent (ReactReconciler.js:46)
    at mountComponentIntoNode (ReactMount.js:104)
    at ReactReconcileTransaction.perform (Transaction.js:140)
    at batchedMountComponentIntoNode (ReactMount.js:126)
    at ReactDefaultBatchingStrategyTransaction.perform (Transaction.js:140)
    at Object.batchedUpdates (ReactDefaultBatchingStrategy.js:62)
    at Object.batchedUpdates (ReactUpdates.js:97)
    at Object._renderNewRootComponent (ReactMount.js:320)
    at Object._renderSubtreeIntoContainer (ReactMount.js:401)
    at Object.render (ReactMount.js:422)
    at Object.<anonymous> (index.js:36)
    at __webpack_require__ (bootstrap e3e2367…:555)
    at fn (bootstrap e3e2367…:86)
    at Object.<anonymous> (bootstrap e3e2367…:578)
    at __webpack_require__ (bootstrap e3e2367…:555)
    at bootstrap e3e2367…:578
    at bootstrap e3e2367…:578

我的代码可在https://github.com/hhimanshu/spicyveggie/tree/cardscards分支)

我不确定有什么不同,但它不起作用

@janzenz
我也尝试了browserHistory.push('/howItWorks')并导入了import browserHistory from 'react-router-dom' ,但得到了undefuned

@Oduig
我试过#/your/link ,但它没有带我去任何地方
我试过/your/link ,但它重新加载页面,我从Material-UI丢失了Drawer Material-UI

这些东西都不适合我。 我的代码在https://github.com/hhimanshu/spicyveggie/tree/cardscards分支),具体提交是https://github.com/hhimanshu/spicyveggie/commit/844b7b7cddf9102995cd2680a783df3b6ef48537 ,可以有人请帮忙吗?

@hhimanshu将此行更改为

import { Link } from 'react-router-dom'

有关 MDN 的更多信息

@DaxChen ,谢谢。 就是这样。 但是,不是当我的页面加载{<Link to="/menu"/>} ,它会加载整个页面并且我的Drawer消失了。

screen shot 2017-04-24 at 1 54 23 pm

@hhimanshu那是因为您在\menu路线中仅使用了Menu组件,因此不会呈现App

MenuSummary嵌套在App或一些布局组件中,并传入各自的子级。

您可以使用 react-devtools 来检查渲染的组件层次结构及其状态!

这与 material-ui 无关,请在 react-router 的教程/文档中阅读更多内容。

+1

React Router HANDLED & NOT HANDLED 链接的解决方法。


如果目标链接由 React Router 处理

MenuItemLink.js

import React from 'react';
import { MenuItem } from 'material-ui/Menu';
import { Route } from 'react-router-dom';

class MenuItemLink extends React.Component {
  render() {
    const {
      to, also,
      ...rest
    } = this.props;

    return (
      <Route
        render={({ history, location }) => (
          <MenuItem
            onClick={() => {
              history.push(to);
              if (typeof also === 'function') {
                also();
              }
            }}
            {...rest}
          />
        )}
      />
    );
  }
}
MenuItemLink.muiName = 'MenuItem';
export default MenuItemLink;

示例代码:

import MenuItemLink from './MenuItemLink';
<Menu ... >
        <MenuItemLink to="/users"
          also={this.handleRequestClose}>Users</MenuItemLink>
</Menu>

如果 React Router 不处理目标链接,即:请求被转发到 API 服务器或其他

点击功能:

    function facebookLoginRedirect () {
      if (window) window.location.href = "/api/auth/facebook"
      return true;
    }

示例代码:

<MenuItem onClick={ facebookLoginRedirect }>Login with Facebook</MenuItem>

我来补充一下,以防其他人也偶然发现它。

在 v3.4 上,您可以这样实现:

import { Link } from 'react-router-dom';
import MenuItem from '@material-ui/core/MenuItem';

...

<MenuItem component={Link} to="/your-path">...</MenuItem>

在不破坏菜单布局的情况下对我有用的唯一解决方案是:
```javascript


通知



轮廓


在不破坏菜单布局的情况下对我有用的唯一解决方案是:

<MenuList>
  <Link to='/your-path' style={{ textDecoration: 'none' }}>
    <MenuItem>
      Notifications
     </MenuItem>
  </Link>
  <Link to='/your-path' style={{ textDecoration: 'none' }}>
    <MenuItem>
      Profile
     </MenuItem>
  </Link>
</MenuList>

@eladlevy这最终会导致语义不佳的HTML。

<ul>
  <a><li/></a>
  <a><li/></a>
</ul>

把它留在这里以防它帮助任何人(运行 v3.9.0)。 我需要一个<Select>来充当react-router-dom <Link>的菜单。 每个链接对应一个语言设置,因此下拉列表将显示查询参数中当前语言的值。

<Select value={currentLanguage}>
  {languages.map(language => (
    <ListItem
      button
      component={btnProps => (
        <Link
          to={ `/things?lang=${ language }` }
          {...btnProps as any}
        />
      )}
      value={language}
      key={language}
    >
      {language}
    </ListItem>
  ))}
</Select>

这是我能找到的最简洁的解决方案,它需要最少的 TypeScript 转换并保持与 Material UI 一致的视觉效果。

@goyney有解决方案,谢谢

我来补充一下,以防其他人也偶然发现它。

在 v3.4 上,您可以这样实现:

import { Link } from 'react-router-dom';
import MenuItem from '@material-ui/core/MenuItem';

...

<MenuItem component={Link} to="/your-path">...</MenuItem>

工作和清洁的解决方案,谢谢❤️

对于外部链接,您需要使用component="a" ,但也要将MenuItem包围在<li>

<MenuList>
    <li>
        <MenuItem
            component="a"
            href="https://google.com"
            target="_blank"
        >Google</MenuItem>
    </li>
</MenuList>

这会生成以下 HTML:

<ul class="MuiList-root MuiList-padding" role="menu" tabindex="-1">
    <li>
        <a class="[...]" tabindex="-1" aria-disabled="false" role="menuitem" href="https://google.com" target="_blank">Google</a>
    </li>
</ul>

假设我有一个弹出菜单并使用

从'react-router-dom'导入{链接};
从'@material-ui/core/MenuItem'导入菜单项;

\\

链接将打开 /your-path 页面,如何关闭弹出菜单?

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

rbozan picture rbozan  ·  3评论

iamzhouyi picture iamzhouyi  ·  3评论

revskill10 picture revskill10  ·  3评论

ghost picture ghost  ·  3评论

mb-copart picture mb-copart  ·  3评论