【问题标题】:Overriding material-ui styles覆盖 Material-ui 样式
【发布时间】:2020-01-30 03:12:50
【问题描述】:

我发现了许多关于覆盖样式的帖子,但与我遇到的问题完全不同。我正在创建样式化的 material-ui 组件并将它们导入我的应用程序的不同部分。我希望能够覆盖来自各种父组件的一些样式。

我有一个按钮组件:

import React from "react";
import { makeStyles } from "@material-ui/styles";

const useStyles = makeStyles({
  buttonBlue: {
    background: "#09a1e2",
    border: "1px solid #09a1e2",
    borderRadius: "5px",
    color: "#ffffff",
    cursor: "pointer",
    fontSize: "1.25rem",
    padding: ".75rem 1.25rem .75rem 1.25rem",
    "&:hover": {
      backgroundColor: "#ffffff",
      color: "#09a1e2"
    }
  },
  buttonWhite: {
    background: "#ffffff",
    border: "1px solid #666666",
    borderRadius: "5px",
    cursor: "pointer",
    fontSize: "1rem",
    padding: ".5rem",
    width: "6rem",
    "&:hover": {
      backgroundColor: "#666666",
      color: "#ffffff"
    }
  }
});

const MediumButton = props => {
  const color = props.color;
  const classes = useStyles();
  return (
    <div>
      {color === "blue" ? (
        <button className={classes.buttonBlue}>{props.buttonText}</button>
      ) : (
        <button className={classes.buttonWhite}>{props.buttonText}</button>
      )}
    </div>
  );
};

export default MediumButton;

我将导入另一个组件。我想在我的新组件上覆盖其中一些样式,但我不太清楚如何。

这是我正在尝试的:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import { withContext } from "../../context/AppContext";
import MediumButton from "../components/MediumButton";

const useStyles = makeStyles({
    root : {
        display: "flex",
    },
    homeButton: {
        background: "white",
        border: "1px solid #09a1e2",
        borderRadius: "5px",
        color: "#09a1e2",
        cursor: "pointer",
        fontSize: "1.25rem",
        padding: ".5rem 3.25rem .5rem 3.25rem",
        textDecoration: 'none',
        "&:hover": {
            backgroundColor: "#ffffff",
            color: "#09a1e2"
        }

    }
});

const PageNotFound = () => {

  const classes = useStyles();
  return (
    <div className={classes.root}>

      <MediumButton className={classes.homeButton} />
    </div>
  );
};

export default withContext(PageNotFound);

我不确定我需要调用什么来覆盖我在 MediumButton 组件上设置的样式。

【问题讨论】:

    标签: css reactjs material-ui


    【解决方案1】:

    如果您允许指定 className 属性,您可以将该 CSS 类 另外 应用到您的组件应用的 CSS 类(而不是 而不是 如 Ido 的选项 1) 所示。如果覆盖是使用makeStyles 创建的,那么只要在导入组件之后调用makeStyles 覆盖调用,它们就会胜过默认样式(请参阅最后的相关答案有关这方面的更多详细信息 - 对于典型用法,这将按照您想要的方式工作)。

    下面是一个如何工作的工作示例。关于我的 MediumButton 示例版本的一些其他方面需要注意:

    • 使用children 而不是buttonText 属性
    • 放置始终应用的常见样式(无论colorprop) into a separate CSS class (mediumButton`如何都应该相同的样式)
    • button 元素中未明确使用的任何其他道具传递给MediumButton。这使得传入事件处理程序(例如onClick)或button(例如disabled)支持的其他属性变得容易,而无需在MediumButton 中添加额外的代码来处理这些道具。
    • 使用 clsx 方便地组合多个类名。 clsx 在 Material-UI 内部使用,所以这不会增加任何东西到你的包大小。

    MediumButton.js

    import React from "react";
    import { makeStyles } from "@material-ui/styles";
    import clsx from "clsx";
    
    const useStyles = makeStyles({
      mediumButton: {
        borderRadius: "5px",
        cursor: "pointer",
        fontSize: "1.25rem",
        padding: ".75rem 1.25rem .75rem 1.25rem",
        margin: 8
      },
      buttonBlue: {
        background: "#09a1e2",
        border: "1px solid #09a1e2",
        color: "#ffffff",
        "&:hover": {
          backgroundColor: "#ffffff",
          color: "#09a1e2"
        }
      },
      buttonWhite: {
        background: "#ffffff",
        border: "1px solid #666666",
        "&:hover": {
          backgroundColor: "#666666",
          color: "#ffffff"
        }
      }
    });
    
    const MediumButton = ({ className, children, color, ...other }) => {
      const classes = useStyles();
      return (
        <button
          {...other}
          className={clsx(
            classes.mediumButton,
            {
              [classes.buttonBlue]: color === "blue",
              [classes.buttonWhite]: color !== "blue"
            },
            className
          )}
        >
          {children}
        </button>
      );
    };
    
    export default MediumButton;
    

    index.js

    import React from "react";
    import ReactDOM from "react-dom";
    import { makeStyles } from "@material-ui/styles";
    
    import MediumButton from "./MediumButton";
    
    const useStyles = makeStyles({
      homeButton: {
        background: "white",
        color: "#09a1e2",
        border: "1px solid #09a1e2",
        padding: ".5rem 3.25rem .5rem 3.25rem",
        textDecoration: "none",
        "&:hover": {
          backgroundColor: "#ffffff",
          color: "#09a1e2"
        }
      }
    });
    function App() {
      const classes = useStyles();
      return (
        <div className="App">
          <MediumButton onClick={() => alert("You clicked me!")}>
            White Button
          </MediumButton>
          <MediumButton color="blue">Blue Button</MediumButton>
          <MediumButton className={classes.homeButton}>Home Button</MediumButton>
          <MediumButton className={classes.homeButton} color="blue">
            Blue Home Button
          </MediumButton>
        </div>
      );
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    

    了解在对通过makeStyles 生成的多个类进行分层时哪些样式会胜出的相关答案:

    【讨论】:

      【解决方案2】:

      自从您创建了 MediumButton,您就可以决定如何允许其他组件覆盖默认样式。

      选项 1:

      替换整个默认样式
      是从父亲那里发送 className 属性(就像你做的那样),并且在 MediumButton 中,如果提供了这些样式:

      const MediumButton = props => {
        const { className, color } = props;
        const classes = useStyles();
      
        return (
          <div>
            {color === "blue" ? (
              <button className={className || classes.buttonBlue}>{props.buttonText}</button>
            ) : (
              <button className={className || classes.buttonWhite}>{props.buttonText}</button>
            )}
          </div>
        );
      };
      

      选项 2:

      仅替换所需的属性,并保留默认样式。
      向 MediumButton 发送 additonalStyles 属性,并在 makeStyles 中处理:

      import React from "react";
      import { makeStyles } from "@material-ui/styles";
      
      const useStyles = makeStyles({
        ........your other styles........
        additionalStyles: props => ({
          ...props
        }),
      });
      
      const MediumButton = props => {
        const { additionalStyles, color } = props;
        const classes = useStyles(additionalStyles);
      
        return (
          <div>
            {color === "blue" ? (
              <button className={`${classes.buttonBlue} ${classes.additionalStyles}`}>
                {props.buttonText}
              </button>
            ) : (
              <button className={`${classes.buttonWhite} ${classes.additionalStyles}`}>
                {props.buttonText}
              </button>
            )}
          </div>
        );
      };
      
      export default MediumButton;
      

      【讨论】:

      • 这将完全覆盖MediumButton 上的样式,但是如果我想保留MediumButton 组件中当前提供的所有样式并只覆盖填充呢?
      猜你喜欢
      • 2019-03-07
      • 2020-05-27
      • 2020-08-10
      • 2021-06-30
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多