【问题标题】:Is there a way to show a Material-UI Drawer nested inside a Grid component?有没有办法显示嵌套在 Grid 组件中的 Material-UI Drawer?
【发布时间】:2019-09-02 07:12:09
【问题描述】:

我正在使用 Material-UI 创建一个 Web 应用程序。主页分为 3 个网格,每个网格有一个 height 和 500px。我想在中间网格内显示一个带有一些操作选项的抽屉。那可能吗?到目前为止,我只能相对于整个屏幕显示它。

这是我使用网格元素的主要组件:

import React, { Fragment } from 'react';
import Grid from '@material-ui/core/Grid';
import Paper from '@material-ui/core/Paper';

const style = {
    Paper: {
        padding: 10,
        marginTop: 5,
        marginBottom: 5,
        height: 500,
        overflowY: 'auto',
        position: 'relative',
    },
    Fab: {
        position: 'absolute',
        top: 5,
        left: 5
    },
}

export default () => {
    return (
        <Fragment>
            <Grid container spacing={1}>
                <Grid item xs={12} sm={4} md={4} lg={2}>
                    <Paper style={style.Paper}>

                    </Paper>
                </Grid>

                <Grid item xs={12} sm={8} md={8} lg={4}>
                    <Paper style={style.Paper}>
                        <ToolbarDrawer />
                    </Paper>
                </Grid>

                <Grid item xs={12} sm={12} md={12} lg={6}>
                    <Paper style={style.Paper}>

                    </Paper>
                </Grid>
            </Grid>
        </Fragment>
    );
}

这是我希望嵌套在中间网格内的抽屉组件:

javascript

import React, { Fragment } from 'react';
import IconButton from '@material-ui/core/IconButton';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
import InboxIcon from '@material-ui/icons/MoveToInbox';
import MailIcon from '@material-ui/icons/Mail';
import { makeStyles } from '@material-ui/core/styles';
import clsx from 'clsx';
import Drawer from '@material-ui/core/Drawer';
import Divider from '@material-ui/core/Divider';
import ListItem from '@material-ui/core/ListItem';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import List from '@material-ui/core/List';
import CssBaseline from '@material-ui/core/CssBaseline';

const drawerWidth = 240;

const useStyles = makeStyles(theme => ({
  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(6) + 1,
    [theme.breakpoints.up('sm')]: {
      width: theme.spacing(7) + 1,
    },
  },
  toolbar: {
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'flex-end',
    padding: theme.spacing(0, 1),
    ...theme.mixins.toolbar,
  }
}));

export default () => {
    const classes = useStyles();

    const [open, setOpen] = React.useState(false);

    function handleToolbarClose() {
        setOpen(!open);
    }

    return (
            <Fragment>
                <CssBaseline />
                <Drawer
                    anchor="right"
                    variant="permanent"
                    className={clsx(classes.drawer, {
                      [classes.drawerOpen]: open,
                      [classes.drawerClose]: !open,
                    })}
                    classes={{
                      paper: clsx({
                        [classes.drawerOpen]: open,
                        [classes.drawerClose]: !open,
                      }),
                    }}
                    open={open}
                >
                    <div className={classes.toolbar}>
                      <IconButton onClick={handleToolbarClose}>
                        {(open) ? <ChevronRightIcon /> : <ChevronLeftIcon />}
                      </IconButton>
                    </div>
                    <Divider />
                    <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>
                </Drawer>

            </Fragment>
        )   
}

【问题讨论】:

    标签: javascript reactjs material-ui


    【解决方案1】:

    看起来您将不得不为此构建一个临时的抽屉组件。以下是您可以开始使用的示例:

    Live demo can be found here

    MakeshiftDrawer 使用List 组件和Slide 转换组件:

    export default function MakeshiftDrawer({ open }) {
      const classes = useStyles();
      const [selectedIndex, setSelectedIndex] = React.useState(1);
    
      function handleListItemClick(event, index) {
        setSelectedIndex(index);
      }
    
      return (
        <Slide direction="right" in={open} mountOnEnter unmountOnExit>
          <div className={classes.root}>
            <List component="nav" aria-label="main mailbox folders">
              <ListItem
                button
                selected={selectedIndex === 0}
                onClick={event => handleListItemClick(event, 0)}
              >
                <ListItemIcon>
                  <InboxIcon />
                </ListItemIcon>
                <ListItemText primary="Inbox" />
              </ListItem>
              <ListItem
                button
                selected={selectedIndex === 1}
                onClick={event => handleListItemClick(event, 1)}
              >
                <ListItemIcon>
                  <DraftsIcon />
                </ListItemIcon>
                <ListItemText primary="Drafts" />
              </ListItem>
            </List>
            <Divider />
            <List component="nav" aria-label="secondary mailbox folder">
              <ListItem
                button
                selected={selectedIndex === 2}
                onClick={event => handleListItemClick(event, 2)}
              >
                <ListItemText primary="Trash" />
              </ListItem>
              <ListItem
                button
                selected={selectedIndex === 3}
                onClick={event => handleListItemClick(event, 3)}
              >
                <ListItemText primary="Spam" />
              </ListItem>
            </List>
          </div>
        </Slide>
      );
    }
    

    MakeshiftDrawer 正在使用中:

    function App() {
      const [isOpen, setIsOpen] = useState(true);
    
      const toggle = () => {
        setIsOpen(!isOpen);
      }
    
      return (
        <div>
          <Grid container direction="row" style={topGridStyle}>
          </Grid>
          <Grid container direction="row" style={midGridStyle}>
            <Grid item>
              <Button variant="contained" color="primary" onClick={toggle}>Toggle</Button>
              <MakeshiftDrawer open={isOpen} />
            </Grid>
          </Grid>
          <Grid container direction="row" style={botGridStyle}>
          </Grid>
        </div>
      );
    }
    

    渲染:

    【讨论】:

      猜你喜欢
      • 2018-08-02
      • 2021-09-01
      • 2019-05-20
      • 1970-01-01
      • 1970-01-01
      • 2016-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多