【问题标题】:How to make sidebar using framework in reactjs?如何在 reactjs 中使用框架制作侧边栏?
【发布时间】:2020-06-16 19:52:04
【问题描述】:

我是 Material UI 的新手,我希望将导航栏和侧边栏作为不同的组件。我已经创建了导航栏组件,但无法将侧边栏创建为单独的组件。谁能帮我做单独的组件?这是我正在浏览的链接“https://material-ui.com/components/drawers/

这里是代码 sn-p -“https://codesandbox.io/s/hshhd”,我希望单独的侧边栏(抽屉)组件与标题组件链接。

标题组件:

import React from 'react';
import { fade, makeStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import Badge from '@material-ui/core/Badge';
import MenuItem from '@material-ui/core/MenuItem';
import Menu from '@material-ui/core/Menu';
import MenuIcon from '@material-ui/icons/Menu';
import SearchIcon from '@material-ui/icons/Search';
import AccountCircle from '@material-ui/icons/AccountCircle';
import NotificationsIcon from '@material-ui/icons/Notifications';
import MoreIcon from '@material-ui/icons/MoreVert';

const useStyles = makeStyles(theme => ({
  grow: {
    flexGrow: 1,
  },
  menuButton: {
    marginRight: theme.spacing(2),
  },
  title: {
    display: 'none',
    [theme.breakpoints.up('sm')]: {
      display: 'block',
    },
  },
  search: {
    position: 'relative',
    borderRadius: theme.shape.borderRadius,
    backgroundColor: fade(theme.palette.common.white, 0.15),
    '&:hover': {
      backgroundColor: fade(theme.palette.common.white, 0.25),
    },
    marginRight: theme.spacing(2),
    marginLeft: 0,
    width: '100%',
    [theme.breakpoints.up('sm')]: {
      marginLeft: theme.spacing(3),
      width: 'auto',
    },
  },
  searchIcon: {
    width: theme.spacing(7),
    height: '100%',
    position: 'absolute',
    pointerEvents: 'none',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  },
  inputRoot: {
    color: 'inherit',
  },
  inputInput: {
    padding: theme.spacing(1, 1, 1, 7),
    transition: theme.transitions.create('width'),
    width: '100%',
    [theme.breakpoints.up('md')]: {
      width: 200,
    },
  },
  sectionDesktop: {
    display: 'none',
    [theme.breakpoints.up('md')]: {
      display: 'flex',
    },
  },
  sectionMobile: {
    display: 'flex',
    [theme.breakpoints.up('md')]: {
      display: 'none',
    },
  },
}));

const Header = () => {
  const classes = useStyles();
  const [anchorEl, setAnchorEl] = React.useState(null);
  const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = React.useState(null);

  const isMenuOpen = Boolean(anchorEl);
  const isMobileMenuOpen = Boolean(mobileMoreAnchorEl);

  const handleProfileMenuOpen = event => {
    setAnchorEl(event.currentTarget);
  };

  const handleMobileMenuClose = () => {
    setMobileMoreAnchorEl(null);
  };

  const handleMenuClose = () => {
    setAnchorEl(null);
    handleMobileMenuClose();
  };

  const handleMobileMenuOpen = event => {
    setMobileMoreAnchorEl(event.currentTarget);
  };

  const menuId = 'primary-search-account-menu';
  const renderMenu = (
    <Menu
      anchorEl={anchorEl}
      anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
      id={menuId}
      keepMounted
      transformOrigin={{ vertical: 'top', horizontal: 'right' }}
      open={isMenuOpen}
      onClose={handleMenuClose}
    >
      <MenuItem onClick={handleMenuClose}>Profile</MenuItem>
      <MenuItem onClick={handleMenuClose}>My account</MenuItem>
    </Menu>
  );

  const mobileMenuId = 'primary-search-account-menu-mobile';
  const renderMobileMenu = (
    <Menu
      anchorEl={mobileMoreAnchorEl}
      anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
      id={mobileMenuId}
      keepMounted
      transformOrigin={{ vertical: 'top', horizontal: 'right' }}
      open={isMobileMenuOpen}
      onClose={handleMobileMenuClose}
    >
      <MenuItem>
        <IconButton aria-label="show 11 new notifications" color="inherit">
          <Badge badgeContent={17} color="secondary">
            <NotificationsIcon />
          </Badge>
        </IconButton>
        <p>Notifications</p>
      </MenuItem>
      <MenuItem onClick={handleProfileMenuOpen}>
        <IconButton
          aria-label="account of current user"
          aria-controls="primary-search-account-menu"
          aria-haspopup="true"
          color="inherit"
        >
          <AccountCircle />
        </IconButton>
        <p>Profile</p>
      </MenuItem>
    </Menu>
  );

  return (
    <div className={classes.grow}>
      <AppBar position="static">
        <Toolbar>
          <IconButton
            edge="start"
            className={classes.menuButton}
            color="inherit"
            aria-label="open drawer"
          >
            <MenuIcon />
          </IconButton>

          <div className={classes.grow} />
          <div className={classes.sectionDesktop}>
            <IconButton aria-label="show 17 new notifications" color="inherit">
              <Badge badgeContent={17} color="secondary">
                <NotificationsIcon />
              </Badge>
            </IconButton>
            <IconButton
              edge="end"
              aria-label="account of current user"
              aria-controls={menuId}
              aria-haspopup="true"
              onClick={handleProfileMenuOpen}
              color="inherit"
            >
              <AccountCircle />
            </IconButton>
          </div>
          <div className={classes.sectionMobile}>
            <IconButton
              aria-label="show more"
              aria-controls={mobileMenuId}
              aria-haspopup="true"
              onClick={handleMobileMenuOpen}
              color="inherit"
            >
              <MoreIcon />
            </IconButton>
          </div>
        </Toolbar>
      </AppBar>
      {renderMobileMenu}
      {renderMenu}
    </div>
  );
}

export default Header;

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

    既然你说你是新手,我想我会多做一点,让你看到可能性和可以说的更好的做法。我已将您的整个代码分为 3 部分:您的主要组件 (App),然后是内容 (Content),然后是侧面菜单/应用栏 (SideMenu)。

    import React from "react";
    import clsx from "clsx";
    import { makeStyles, useTheme } from "@material-ui/core/styles";
    import Drawer from "@material-ui/core/Drawer";
    import AppBar from "@material-ui/core/AppBar";
    import Toolbar from "@material-ui/core/Toolbar";
    import List from "@material-ui/core/List";
    import CssBaseline from "@material-ui/core/CssBaseline";
    import Typography from "@material-ui/core/Typography";
    import Divider from "@material-ui/core/Divider";
    import IconButton from "@material-ui/core/IconButton";
    import MenuIcon from "@material-ui/icons/Menu";
    import ChevronLeftIcon from "@material-ui/icons/ChevronLeft";
    import ChevronRightIcon from "@material-ui/icons/ChevronRight";
    import ListItem from "@material-ui/core/ListItem";
    import ListItemIcon from "@material-ui/core/ListItemIcon";
    import ListItemText from "@material-ui/core/ListItemText";
    import InboxIcon from "@material-ui/icons/MoveToInbox";
    import MailIcon from "@material-ui/icons/Mail";
    
    const drawerWidth = 240;
    
    const useStyles = makeStyles(theme => ({
      root: {
        display: "flex"
      },
      appBar: {
        zIndex: theme.zIndex.drawer + 1,
        transition: theme.transitions.create(["width", "margin"], {
          easing: theme.transitions.easing.sharp,
          duration: theme.transitions.duration.leavingScreen
        })
      },
      appBarShift: {
        marginLeft: drawerWidth,
        width: `calc(100% - ${drawerWidth}px)`,
        transition: theme.transitions.create(["width", "margin"], {
          easing: theme.transitions.easing.sharp,
          duration: theme.transitions.duration.enteringScreen
        })
      },
      menuButton: {
        marginRight: 36
      },
      hide: {
        display: "none"
      },
      drawer: {
        width: drawerWidth,
        flexShrink: 0,
        whiteSpace: "nowrap"
      },
      drawerOpen: {
        width: drawerWidth,
        transition: theme.transitions.create("width", {
          easing: theme.transitions.easing.sharp,
          duration: theme.transitions.duration.enteringScreen
        })
      },
      drawerClose: {
        transition: theme.transitions.create("width", {
          easing: theme.transitions.easing.sharp,
          duration: theme.transitions.duration.leavingScreen
        }),
        overflowX: "hidden",
        width: theme.spacing(7) + 1,
        [theme.breakpoints.up("sm")]: {
          width: theme.spacing(9) + 1
        }
      },
      toolbar: {
        display: "flex",
        alignItems: "center",
        justifyContent: "flex-end",
        padding: theme.spacing(0, 1),
        ...theme.mixins.toolbar
      },
      content: {
        flexGrow: 1,
        padding: theme.spacing(3)
      }
    }));
    
    // This is the component that controls what to show
    export default function App() {
      const classes = useStyles();
    
      return (
        <div className={classes.root}>
          <CssBaseline />
          <AppBarMenu />
          <Content />
        </div>
      );
    }
    
    // This is the content component
    function Content() {
      const classes = useStyles();
    
      return (
        <React.Fragment>
          <main className={classes.content}>
            <div className={classes.toolbar} />
            <Typography paragraph>
              Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
              eiusmod tempor incididunt ut labore et dolore magna aliqua. Rhoncus
              dolor purus non enim praesent elementum facilisis leo vel. Risus at
              ultrices mi tempus imperdiet. Semper risus in hendrerit gravida rutrum
              quisque non tellus. Convallis convallis tellus id interdum velit
              laoreet id donec ultrices. Odio morbi quis commodo odio aenean sed
              adipiscing. Amet nisl suscipit adipiscing bibendum est ultricies
              integer quis. Cursus euismod quis viverra nibh cras. Metus vulputate
              eu scelerisque felis imperdiet proin fermentum leo. Mauris commodo
              quis imperdiet massa tincidunt. Cras tincidunt lobortis feugiat
              vivamus at augue. At augue eget arcu dictum varius duis at consectetur
              lorem. Velit sed ullamcorper morbi tincidunt. Lorem donec massa sapien
              faucibus et molestie ac.
            </Typography>
            <Typography paragraph>
              Consequat mauris nunc congue nisi vitae suscipit. Fringilla est
              ullamcorper eget nulla facilisi etiam dignissim diam. Pulvinar
              elementum integer enim neque volutpat ac tincidunt. Ornare suspendisse
              sed nisi lacus sed viverra tellus. Purus sit amet volutpat consequat
              mauris. Elementum eu facilisis sed odio morbi. Euismod lacinia at quis
              risus sed vulputate odio. Morbi tincidunt ornare massa eget egestas
              purus viverra accumsan in. In hendrerit gravida rutrum quisque non
              tellus orci ac. Pellentesque nec nam aliquam sem et tortor. Habitant
              morbi tristique senectus et. Adipiscing elit duis tristique
              sollicitudin nibh sit. Ornare aenean euismod elementum nisi quis
              eleifend. Commodo viverra maecenas accumsan lacus vel facilisis. Nulla
              posuere sollicitudin aliquam ultrices sagittis orci a.
            </Typography>
          </main>
        </React.Fragment>
      );
    }
    
    // This is the appbar component
    function AppBarMenu() {
      const classes = useStyles();
      const theme = useTheme();
      const [open, setOpen] = React.useState(false);
    
      const handleDrawerOpen = () => {
        setOpen(true);
      };
    
      const handleDrawerClose = () => {
        setOpen(false);
      };
    
      return (
        <div className={classes.root}>
          <CssBaseline />
          <AppBar
            position="fixed"
            className={clsx(classes.appBar, {
              [classes.appBarShift]: open
            })}
          >
            <Toolbar>
              <IconButton
                color="inherit"
                aria-label="open drawer"
                onClick={handleDrawerOpen}
                edge="start"
                className={clsx(classes.menuButton, {
                  [classes.hide]: open
                })}
              >
                <MenuIcon />
              </IconButton>
              <Typography variant="h6" noWrap>
                Mini variant drawer
              </Typography>
            </Toolbar>
          </AppBar>
          <Drawer
            variant="permanent"
            className={clsx(classes.drawer, {
              [classes.drawerOpen]: open,
              [classes.drawerClose]: !open
            })}
            classes={{
              paper: clsx({
                [classes.drawerOpen]: open,
                [classes.drawerClose]: !open
              })
            }}
          >
            <div className={classes.toolbar}>
              <IconButton onClick={handleDrawerClose}>
                {theme.direction === "rtl" ? (
                  <ChevronRightIcon />
                ) : (
                  <ChevronLeftIcon />
                )}
              </IconButton>
            </div>
            <Divider />
            <SideMenu />
          </Drawer>
        </div>
      );
    }
    
    // This is the sidemenu component
    function SideMenu() {
      return (
        <div>
          <List>
            {["Inbox", "Starred", "Send email", "Drafts"].map((text, index) => (
              <ListItem button key={text}>
                <ListItemIcon>
                  {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
                </ListItemIcon>
                <ListItemText primary={text} />
              </ListItem>
            ))}
          </List>
          <Divider />
          <List>
            {["All mail", "Trash", "Spam"].map((text, index) => (
              <ListItem button key={text}>
                <ListItemIcon>
                  {index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
                </ListItemIcon>
                <ListItemText primary={text} />
              </ListItem>
            ))}
          </List>
        </div>
      );
    }
    

    这里还有代码链接:https://codesandbox.io/s/material-demo-ccf27

    【讨论】:

    • 嗨,这很好,但我只想要 AppBar 和 Sidebar 作为独立组件,而我可以在 App.js 组件中调用这两个组件
    • 所以您只希望侧边栏和应用栏作为单独的组件调用主应用程序?
    • 是的,正确:)
    • 编辑了我的答案。请检查并告诉我
    • 非常感谢 :)。感谢您在这个问题上帮助我:)。
    猜你喜欢
    • 2015-10-20
    • 1970-01-01
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2019-01-22
    • 2021-09-07
    相关资源
    最近更新 更多