Tom*_*Tom 22 css emotion reactjs material-ui css-in-js
我从 Mui 4 迁移到 5,想知道如何使用类名。如果我想将某些样式仅应用于一个组件,则可以使用 SX 属性。但是,我正在努力为多个组件使用相同的类。在 v4 中,我的代码如下所示:
export const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
padding: theme.spacing(1),
margin: 'auto',
},
})
)
Run Code Online (Sandbox Code Playgroud)
我可以在任何组件中导入这个useStyles钩子并像这样使用它:
const classes = useStyles()
...
<div className={classes.root}>...</div>
Run Code Online (Sandbox Code Playgroud)
该文档说,我可以“用类名覆盖样式”,但他们没有告诉如何做到这一点: https://mui.com/customization/how-to-customize/#overriding-styles-with-class -名称
我是否必须将这些样式放入外部 CSS 文件中?
.Button {
color: black;
}
Run Code Online (Sandbox Code Playgroud)
我宁愿在我的 ts 文件中定义样式。
我还找到了这个迁移指南: https ://next.material-ui.com/guides/migration-v4/#migrate-makestyles-to-emotion
我不喜欢方法一,因为使用这个 Root 包装器,有条件地应用类很不方便。(特别是对于打字稿,有一些开销)方法二带有外部依赖项和一些样板代码。
理想情况下,我会使用这样的样式,也许在样式对象周围使用一个说唱歌手函数:
export const root = {
padding: theme.spacing(1),
margin: 'auto',
}
<div className={root}>...</div>
Run Code Online (Sandbox Code Playgroud)
当然,最后一种方法不起作用,因为 className 需要一个字符串作为输入。有人知道有很少样板代码的替代方案吗?
Mat*_*ong 15
我建议您查看情感的文档以了解详细信息。这个sx道具实际上是传递给情感的。
你可以这样做:
const sx = {
"& .MuiDrawer-paper": {
width: drawerWidth
}
};
<Drawer sx={sx}/>
Run Code Online (Sandbox Code Playgroud)
相当于 MUI v4
const useStyles = makeStyles({
drawerPaper: {
width: drawerWidth,
}
});
const classes = useStyles();
<Drawer
classes={{
paper: classes.drawerPaper,
}}
/>
Run Code Online (Sandbox Code Playgroud)
回答你的确切问题,有一些用例(我认为你的不是其中之一,你应该使用样式组件),但是对于像我这样偶然发现它并想要“这个问题的确切答案”而不是“这样做”的人来说相反”,这就是您检索类名的方法。
到目前为止,这还没有记录。
对于使用情感的功能组件,这里有一个用例,其中您有一个第三方组件,该组件需要的不是一个而是多个类名,或者 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} />
)
}
Run Code Online (Sandbox Code Playgroud)
当您有一个类组件时,如果您使用主题,则需要使用未记录的withTheme组件并包装您的类。@mui/material/styles
当它不是一个用例时
import { styled } from "@mui/material/styles";
const ThrirdPartyStyled = styled(ThirdPartyComponent)(({theme}) => ({
color: theme.palette.success.contrastText
}))
Run Code Online (Sandbox Code Playgroud)
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",
}))
Run Code Online (Sandbox Code Playgroud)
即使每个颜色都有某种形式的自定义颜色,您也只需在新的 ThrirdPartyStyled 上使用“sx”即可。
import { styled } from "@mui/material/styles";
const ThrirdPartyStyled = styled(ThirdPartyComponent)(({theme}) => ({
color: theme.palette.success.contrastText
}))
Run Code Online (Sandbox Code Playgroud)
现在,“大概”很酷的是,你的样式现在只是一个对象,你可以导入它并在任何地方使用它,而无需 makeStyles 或 withStyles,据说是一个优势,即使说实话,我从未使用过它周围的出口/进口;不过,代码看起来更干净一些。
您似乎想使用它,所以您所做的就是。
export const myStyles {
// your styles here
}
Run Code Online (Sandbox Code Playgroud)
因为这个对象在内存中是等价的,并且它总是同一个对象,更容易搞乱样式,理论上它应该和你的钩子一样有效甚至更有效(如果它经常重新渲染,即使设置可能会发生)更长),它将相同的函数存储在内存中,但每次都返回一个新对象。
现在,您可以在您认为合理的任何地方使用这些 myStyles,无论是使用样式组件还是通过分配给 sx。
您可以进一步优化,比如说,如果您始终使用以相同方式设置样式的 div,那么样式化组件MyStyledDiv应该更快,因为它是相同的并且每次都会完成。这要快多少?根据一些消息来源,速度快了 55%,对我来说,重构需要 4 周的时间,而且 JSS 与情感的兼容性很差,所有与 SSR 的混合都会使一切变得无法使用、缓慢且损坏,所以让我们看看到那时整体重构的时间。
| 归档时间: |
|
| 查看次数: |
22697 次 |
| 最近记录: |