我从Mui 4迁移到了5,不知道如何使用类名。如果我只想将某些样式应用于一个组件,可以使用SX属性。然而,我在为多个组件使用同一个类而苦苦挣扎。在v4中,我的代码如下所示:
export const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
padding: theme.spacing(1),
margin: 'auto',
},
})
)我可以将这个useStyles钩子导入到任何组件中,并像这样使用它:
const classes = useStyles()
...
<div className={classes.root}>...</div>这个文档说,我可以‘用类名覆盖样式’,但是他们没有告诉我怎么做:https://mui.com/customization/how-to-customize/#overriding-styles-with-class-names
我必须把这些样式放在一个外部CSS文件中吗?
.Button {
color: black;
}我宁愿在ts文件中定义样式。
我还找到了这个迁移指南:https://next.material-ui.com/guides/migration-v4/#migrate-makestyles-to-emotion
我不喜欢第一种方法,因为使用这个Root包装器,有条件地应用一个类是不方便的。(特别是对于typescript,有一些开销)方法二带有一个外部依赖和一些样板代码。
理想情况下,我会使用这样的样式,可能会在样式对象周围使用一个rapper函数:
export const root = {
padding: theme.spacing(1),
margin: 'auto',
}
<div className={root}>...</div>当然,最后一种方法不起作用,因为className需要一个字符串作为输入。有没有人知道用小样本代码的替代方案?
发布于 2021-09-20 09:55:01
我建议你看一下emotion的文档来了解细节。sx道具实际上传递给了情感。
你可以这样做:
const sx = {
"& .MuiDrawer-paper": {
width: drawerWidth
}
};
<Drawer sx={sx}/>等效于MUI v4
const useStyles = makeStyles({
drawerPaper: {
width: drawerWidth,
}
});
const classes = useStyles();
<Drawer
classes={{
paper: classes.drawerPaper,
}}
/>发布于 2022-02-11 13:45:47
回答你的确切问题,有用例(我认为你的用例不在其中,你应该使用样式组件),但是对于像我这样偶然发现它并想要“这个问题的确切答案”而不是“改为这样做”的人来说,这是你如何实现检索类名的。
到目前为止,这还没有记录在案。
对于功能组件,使用情感,这里是一个用例,其中你有一个第三方组件需要,而不是一个,而是许多个类名,或者className属性不是你想要传递属性的地方。
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不是用例时使用
import { styled } from "@mui/material/styles";
const ThrirdPartyStyled = styled(ThirdPartyComponent)(({theme}) => ({
color: theme.palette.success.contrastText
}))即使您有动态样式
也是如此
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“。
重用样式时
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的情况下在任何地方使用它,这被认为是一个优势,即使说实话,我从来没有使用过导出/导入;尽管如此,代码似乎更简洁了。
你似乎想使用它,所以你所要做的就是。
export const myStyles {
// your styles here
}因为这个对象在内存中是等价的,而且它总是同一个对象,更容易搞乱样式,所以理论上它应该和你的钩子一样有效,甚至比钩子更有效(如果它经常重新渲染,即使设置可能更长),它在内存中存储相同的函数,但每次都返回一个新的对象。
现在,您可以在您认为合理的任何地方使用这些myStyles,无论是带有样式的组件,还是通过分配给sx。
你可以进一步优化,比方说,如果你使用的MyStyledDiv总是以相同的方式设置样式,那么设置样式的组件div应该更快,因为它是相同的,并且每次都是这样做的。这个速度有多快?根据一些消息来源55%的速度,对我来说,这需要4周的重构,JSS与情感的兼容性很差,所有与SSR的混合正在使一切变得不可用、缓慢和破碎,所以在那之前让我们看看整个重构的时候。
发布于 2021-10-31 02:26:23
如果您使用makeStyles或withStyles来提供CSS类,您可以按照下面的说明进行操作。
https://stackoverflow.com/questions/69251569
复制相似问题