如何为MUI V5组件设置样式?寻求替代sx props的类样式方案
MUI V5 通用样式方案:替代重复sx props的类名方式
我在项目中使用MUI V5组件,现在都是用sx props给组件加样式,但每个组件都重复写sx太繁琐了。我想找像styled-components那样给组件应用自定义类的方式,知道MUI的styled方法,但它主要用来创建可复用组件,我需要能给任意组件用的通用样式方案。
我的代码示例:
const theme = useTheme(); return ( <Box sx={{ border: '1px solid red', flex: 'auto', paddingLeft: '8px' }}> <Box sx={{ width: '100%', height: '46px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', background: theme.palette['P-10'], padding: '8px 24px' }} > </Box> <Box sx={{ border: '1px solid green' }}>{AreaChartComp}</Box> </Box> );
你看我这里写了3次sx,不想再这么做,希望换成传递类名的方式来设置样式。
可行的通用样式方案
1. 使用makeStyles(V5兼容方案)
虽然MUI V5主推sx和styled,但仍可通过@mui/styles里的makeStyles创建类名,直接传递给任意MUI组件的className属性:
先安装依赖(未安装时执行):
npm install @mui/styles
创建并使用样式:
import { makeStyles } from '@mui/styles'; import { useTheme } from '@mui/material/styles'; import { Box } from '@mui/material'; const useStyles = makeStyles((theme) => ({ outerBox: { border: '1px solid red', flex: 'auto', paddingLeft: '8px' }, headerBox: { width: '100%', height: '46px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', background: theme.palette['P-10'], padding: '8px 24px' }, chartBox: { border: '1px solid green' } })); const MyComponent = () => { const theme = useTheme(); const classes = useStyles(theme); return ( <Box className={classes.outerBox}> <Box className={classes.headerBox}></Box> <Box className={classes.chartBox}>{AreaChartComp}</Box> </Box> ); };
2. 用styled创建灵活的样式组件
如果不想用遗留方案,可通过MUI V5的styled生成专属样式组件,既符合V5设计理念,也能避免重复写sx:
import { styled } from '@mui/material/styles'; import Box from '@mui/material/Box'; // 预定义带样式的组件 const OuterBox = styled(Box)(({ theme }) => ({ border: '1px solid red', flex: 'auto', paddingLeft: '8px' })); const HeaderBox = styled(Box)(({ theme }) => ({ width: '100%', height: '46px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', background: theme.palette['P-10'], padding: '8px 24px' })); const ChartBox = styled(Box)(({ theme }) => ({ border: '1px solid green' })); // 使用时直接调用组件 const MyComponent = () => { return ( <OuterBox> <HeaderBox></HeaderBox> <ChartBox>{AreaChartComp}</ChartBox> </OuterBox> ); };
3. CSS Modules方案
如果项目支持CSS Modules,可直接编写传统CSS文件,导入类名后传递给MUI组件:
创建styles.module.css:
.outerBox { border: 1px solid red; flex: auto; padding-left: 8px; } .headerBox { width: 100%; height: 46px; display: flex; align-items: center; justify-content: space-between; padding: 8px 24px; } .chartBox { border: 1px solid green; }
组件中导入使用:
import styles from './styles.module.css'; import { useTheme } from '@mui/material/styles'; import { Box } from '@mui/material'; const MyComponent = () => { const theme = useTheme(); return ( <Box className={styles.outerBox}> <Box className={styles.headerBox} style={{ background: theme.palette['P-10'] }}></Box> <Box className={styles.chartBox}>{AreaChartComp}</Box> </Box> ); };
总结
- 追求类名直接传递的体验,选
makeStyles最贴合需求; - 拥抱V5新特性,
styled创建专属组件的方式更优雅,适合高频复用场景; - 习惯传统CSS写法,CSS Modules是不错的选择,结合主题变量也能适配MUI设计系统。
内容的提问来源于stack exchange,提问作者Rahul Chauhan
相关产品推荐
相关产品推荐

