首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Material UI 5类名称样式

Material UI 5类名称样式
EN

Stack Overflow用户
提问于 2021-09-20 08:50:59
回答 3查看 3.6K关注 0票数 7

我从Mui 4迁移到了5,不知道如何使用类名。如果我只想将某些样式应用于一个组件,可以使用SX属性。然而,我在为多个组件使用同一个类而苦苦挣扎。在v4中,我的代码如下所示:

代码语言:javascript
复制
export const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    root: {
      padding: theme.spacing(1),
      margin: 'auto',
    },
  })
)

我可以将这个useStyles钩子导入到任何组件中,并像这样使用它:

代码语言:javascript
复制
const classes = useStyles()
...
<div className={classes.root}>...</div>

这个文档说,我可以‘用类名覆盖样式’,但是他们没有告诉我怎么做:https://mui.com/customization/how-to-customize/#overriding-styles-with-class-names

我必须把这些样式放在一个外部CSS文件中吗?

代码语言:javascript
复制
.Button {
  color: black;
}

我宁愿在ts文件中定义样式。

我还找到了这个迁移指南:https://next.material-ui.com/guides/migration-v4/#migrate-makestyles-to-emotion

我不喜欢第一种方法,因为使用这个Root包装器,有条件地应用一个类是不方便的。(特别是对于typescript,有一些开销)方法二带有一个外部依赖和一些样板代码。

理想情况下,我会使用这样的样式,可能会在样式对象周围使用一个rapper函数:

代码语言:javascript
复制
export const root = {
  padding: theme.spacing(1),
  margin: 'auto',
}

<div className={root}>...</div>

当然,最后一种方法不起作用,因为className需要一个字符串作为输入。有没有人知道用小样本代码的替代方案?

EN

回答 3

Stack Overflow用户

发布于 2021-09-20 09:55:01

我建议你看一下emotion的文档来了解细节。sx道具实际上传递给了情感。

你可以这样做:

代码语言:javascript
复制
const sx = {
  "& .MuiDrawer-paper": {
    width: drawerWidth
  }
};
<Drawer sx={sx}/>

等效于MUI v4

代码语言:javascript
复制
const useStyles = makeStyles({
  drawerPaper: {
    width: drawerWidth,
  }
});

const classes = useStyles();

<Drawer
  classes={{
    paper: classes.drawerPaper,
  }}
/>
票数 5
EN

Stack Overflow用户

发布于 2022-02-11 13:45:47

回答你的确切问题,有用例(我认为你的用例不在其中,你应该使用样式组件),但是对于像我这样偶然发现它并想要“这个问题的确切答案”而不是“改为这样做”的人来说,这是你如何实现检索类名的。

到目前为止,这还没有记录在案。

对于功能组件,使用情感,这里是一个用例,其中你有一个第三方组件需要,而不是一个,而是许多个类名,或者className属性不是你想要传递属性的地方。

代码语言:javascript
复制
import { css, Theme, useTheme } from "@mui/material/styles";
import { css as emotionCss } from "@emotion/css";

const myStyles = {
  basicClass: {
    marginLeft: "1rem",
    marginRight: "1rem",
    paddingLeft: "1rem",
    paddingRight: "1rem",
  },
  optionClass: (theme: Theme) => ({
    [theme.breakpoints.down(theme.breakpoints.values.md)]: {
      display: "none",
    }
  })
}

function MyComponent() {
  cons theme = useTheme();

  // first we need to convert to something emotion can understand
  const basicClass = css(myStyles.basicClass);
  const optionClass = css(myStyles.optionClass(theme));

  // now we can pass to emotion
  const basicClassName = emotionCss(basicClass.styles);
  const optionClassName = emotionCss(optionClass.styles);

  return (
    <ThirdPartyComponent basicClassName={basicClassName} optionClassName={optionClassName} />
  )
}

当你有一个类组件时,如果你使用主题,你需要使用来自@mui/material/styles的也没有文档记录的withTheme并包装你的类。

当IT不是用例时使用

  1. 当组件使用单个className属性时,只需使用样式组件即可。

代码语言:javascript
复制
import { styled } from "@mui/material/styles";

const ThrirdPartyStyled = styled(ThirdPartyComponent)(({theme}) => ({
  color: theme.palette.success.contrastText
}))

即使您有动态样式

也是如此

代码语言:javascript
复制
import { styled } from "@mui/material/styles";

interface IThrirdPartyStyledExtraProps {
  fullWidth?: boolean;
}

const ThrirdPartyStyled = styled(ThirdPartyComponent, {
  shouldForwardProp: (prop) => prop !== "fullWidth"
})<IThrirdPartyStyledExtraProps>(({theme, fullWidth}) => ({
  color: theme.palette.success.contrastText,
  width: fullWidth ? "100%" : "auto",
}))

即使每一个都有某种形式的自定义颜色,你也可以在你的新ThrirdPartyStyled上使用"sx“。

  1. 当您正尝试围绕(您的用例)

重用样式时

代码语言:javascript
复制
const myReusableStyle = {
  color: "red",
}

// better
const MyStyledDiv = styled("div")(myReusableStyle);
// questionable
const MySpanWithoutStyles = styled("span")();

// better
const MyDrawerStyled = styled(Drawer)(myReusableStyle);

function MyComponent() {
  return (
    <MyStyledDiv>
      questionable usage because it is less clean:
      <MySpanWithoutStyles sx={myReusableStyle}>hello</MySpanWithoutStyles>
      <MySpanWithoutStyles sx={myReusableStyle}>world</MySpanWithoutStyles>

      these two are equivalent:
      <MyDrawerStyled />
      <Drawer sx={myReusableStyle} />
    </MyStyledDiv>
  )
}

现在“大概”很酷的是,你的风格现在只是一个对象,你可以导入它并在没有makeStyles或withStyles的情况下在任何地方使用它,这被认为是一个优势,即使说实话,我从来没有使用过导出/导入;尽管如此,代码似乎更简洁了。

你似乎想使用它,所以你所要做的就是。

代码语言:javascript
复制
export const myStyles {
  // your styles here
}

因为这个对象在内存中是等价的,而且它总是同一个对象,更容易搞乱样式,所以理论上它应该和你的钩子一样有效,甚至比钩子更有效(如果它经常重新渲染,即使设置可能更长),它在内存中存储相同的函数,但每次都返回一个新的对象。

现在,您可以在您认为合理的任何地方使用这些myStyles,无论是带有样式的组件,还是通过分配给sx。

你可以进一步优化,比方说,如果你使用的MyStyledDiv总是以相同的方式设置样式,那么设置样式的组件div应该更快,因为它是相同的,并且每次都是这样做的。这个速度有多快?根据一些消息来源55%的速度,对我来说,这需要4周的重构,JSS与情感的兼容性很差,所有与SSR的混合正在使一切变得不可用、缓慢和破碎,所以在那之前让我们看看整个重构的时候。

票数 0
EN

Stack Overflow用户

发布于 2021-10-31 02:26:23

如果您使用makeStyles或withStyles来提供CSS类,您可以按照下面的说明进行操作。

CSS overrides created by makeStyles

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69251569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档