如何在 MUI V5 中正确使用 Styled()

Moe*_*Moe 8 javascript typescript reactjs material-ui

我在尝试更大规模地使用 MUI Styled () 时遇到问题:有人可以看一下我们在之前版本中使用的代码,并让我知道如何在 MUI V5 中复制它。

老办法:

const useStyles = makeStyles((theme) => ({
  root: {
    backgroundColor: "#fdfdff",
  },
  pageHeader: {
    padding: theme.spacing(4),
    display: "flex",
    marginBottom: theme.spacing,
  },
  pageIcon: {
    display: "inline-block",
    padding: theme.spacing(2),
    color: "#3c44b1",
  },
  pageTitle: {
    paddingLeft: theme.spacing(4),
    "& .MuiTypography-subtitle2": {
      opacity: "0.6",
    },
  },
}));
export default function PageHeader(props) {
  const classes = useStyles();
  const { title, subTitle, icon } = props;
  return (
    <Paper elevation={0} square className={classes.root}>
      <div className={classes.pageHeader}>
        <Card className={classes.pageIcon}>{icon}</Card>
        <div className={classes.pageTitle}>
          <Typography variant="h6" component="div">
            {title}
          </Typography>
          <Typography variant="subtitle2" component="div">
            {subTitle}
          </Typography>
        </div>
      </div>
    </Paper>
  );
}
Run Code Online (Sandbox Code Playgroud)

编辑 v4 示例

我尝试在 MUI V5 中完成相同的任务但无法正常工作。它渲染了,但看起来不一样,而且到处都是。

const rootStyle = styled("div")({
  backgroundColor: "#fdfdff",
});
const headerStyle = styled("div")(({ theme }) => ({
  padding: theme.spacing(4),
  display: "flex",
  marginBottom: theme.spacing,
}));
const iconStyle = styled("div")(({ theme }) => ({
  display: "inline-block",
  padding: theme.spacing(2),
  color: "#3c44b1",
}));
const titleStyle = styled("div")(({ theme }) => ({
  paddingLeft: theme.spacing(4),
  "& .MuiTypography-subtitle2": {
    opacity: "0.6",
  },
}));

export default function PageHeader(props) {
  const { title, subTitle, icon } = props;
  return (
    <rootStyle>
      <Paper elevation={0} square>
        <headerStyle>
          <iconStyle>
            <Card>{icon}</Card>
          </iconStyle>
          <titleStyle>
            <Typography variant="h6" component="div">
              {title}
            </Typography>
            <Typography variant="subtitle2" component="div">
              {subTitle}
            </Typography>
          </titleStyle>
        </headerStyle>
      </Paper>
    </rootStyle>
  );
}
Run Code Online (Sandbox Code Playgroud)

我是 MUI 新手,并且没有很多示例来涵盖这一点。我真的很感谢你的帮助!

Rya*_*ell 8

下面是代码的 v5 版本,其外观与 v4 版本相同。我为道具添加了默认值只是为了演示目的。

您有两个主要问题:

  1. 您添加了额外的 div 层来进行样式设置,而不是对最初接收样式的元素进行样式设置(例如Paper, Card)。

  2. 您将styleddiv 分配给以小写字母开头的变量名称,这导致它们被呈现为 DOM 标签而不是组件(因此样式将被完全忽略)。

来自https://reactjs.org/docs/components-and-props.html#rendering-a-component

React 将以小写字母开头的组件视为 DOM 标签。

import Paper from "@mui/material/Paper";
import Card from "@mui/material/Card";
import Typography from "@mui/material/Typography";
import { styled } from "@mui/material/styles";
import PersonIcon from "@mui/icons-material/Person";

const StyledPaper = styled(Paper)({
  backgroundColor: "#fdfdff"
});
const HeaderDiv = styled("div")(({ theme }) => ({
  padding: theme.spacing(4),
  display: "flex",
  marginBottom: theme.spacing
}));
const StyledCard = styled(Card)(({ theme }) => ({
  display: "inline-block",
  padding: theme.spacing(2),
  color: "#3c44b1"
}));
const TitleDiv = styled("div")(({ theme }) => ({
  paddingLeft: theme.spacing(4),
  "& .MuiTypography-subtitle2": {
    opacity: "0.6"
  }
}));

export default function PageHeader(props) {
  const {
    title = "Title",
    subTitle = "sub-title",
    icon = <PersonIcon />
  } = props;
  return (
    <StyledPaper elevation={0} square>
      <HeaderDiv>
        <StyledCard>{icon}</StyledCard>
        <TitleDiv>
          <Typography variant="h6" component="div">
            {title}
          </Typography>
          <Typography variant="subtitle2" component="div">
            {subTitle}
          </Typography>
        </TitleDiv>
      </HeaderDiv>
    </StyledPaper>
  );
}
Run Code Online (Sandbox Code Playgroud)

编辑 v5 示例

将 v4 代码转换为 v5 的另一种(更简洁)方法是使用sxprop:

import Paper from "@mui/material/Paper";
import Card from "@mui/material/Card";
import Typography from "@mui/material/Typography";
import PersonIcon from "@mui/icons-material/Person";
import Box from "@mui/material/Box";

export default function PageHeader(props) {
  const {
    title = "Title",
    subTitle = "sub-title",
    icon = <PersonIcon />
  } = props;
  return (
    <Paper elevation={0} square sx={{ bgcolor: "#fdfdff" }}>
      <Box sx={{ p: 4, display: "flex", mb: 1 }}>
        <Card sx={{ display: "inline-block", p: 2, color: "#3c44b1" }}>
          {icon}
        </Card>
        <Box sx={{ pl: 4, "& .MuiTypography-subtitle2": { opacity: 0.6 } }}>
          <Typography variant="h6" component="div">
            {title}
          </Typography>
          <Typography variant="subtitle2" component="div">
            {subTitle}
          </Typography>
        </Box>
      </Box>
    </Paper>
  );
}
Run Code Online (Sandbox Code Playgroud)

使用 sx 编辑 v5 示例

这是使用单个styled调用的又一个选项,尽管在我看来,这比其他选项更难以维护:

import Paper from "@mui/material/Paper";
import Card from "@mui/material/Card";
import Typography from "@mui/material/Typography";
import { styled } from "@mui/material/styles";
import PersonIcon from "@mui/icons-material/Person";

const StyledPaper = styled(Paper)(({ theme }) => ({
  backgroundColor: "#fdfdff",
  "& > div": {
    padding: theme.spacing(4),
    display: "flex",
    marginBottom: theme.spacing(1),
    "& .MuiCard-root": {
      display: "inline-block",
      padding: theme.spacing(2),
      color: "#3c44b1"
    },
    "& > div": {
      paddingLeft: theme.spacing(4),
      "& .MuiTypography-subtitle2": {
        opacity: "0.6"
      }
    }
  }
}));

export default function PageHeader(props) {
  const {
    title = "Title",
    subTitle = "sub-title",
    icon = <PersonIcon />
  } = props;
  return (
    <StyledPaper elevation={0} square>
      <div>
        <Card>{icon}</Card>
        <div>
          <Typography variant="h6" component="div">
            {title}
          </Typography>
          <Typography variant="subtitle2" component="div">
            {subTitle}
          </Typography>
        </div>
      </div>
    </StyledPaper>
  );
}
Run Code Online (Sandbox Code Playgroud)

使用一种风格的调用编辑 v5 示例