用途
该资料介绍 MUI 中两种主要的组件样式 API:sx prop 与 styled() 函数,帮助开发者在不同复用场景中选择合适的样式方案。
主要能力
sx prop
sx 接受 CSS 的超集,取值可引用主题 token、响应断点、使用简写别名。它可用于每个 MUI 组件以及 Box 原语。
- 基本用法:支持驼峰式 CSS 属性,例如
backgroundColor、borderRadius、boxShadow;支持主题 token 引用,例如color: 'primary.main'、bgcolor: 'background.paper';支持排版变体,例如typography: 'h4'。 - 系统简写:单字母别名映射到 CSS 属性,仅在
sx(以及带系统工具的styled)中有效,不支持普通 Emotion。包括m、p、mx、my、px、py、mt、mb、ml、mr、gap,以及width: 1表示 100%(分数映射为百分比)等。 - 主题感知回调:使用
(theme) => ({...})形式访问无法用 token 字符串表达的主题值,例如依据theme.palette.mode计算颜色、theme.spacing间距计算、theme.transitions过渡配置。 - 响应式取值——对象语法:以断点名称为键,值从命名断点向上(移动优先)生效,如
xs: '100%'、sm: '80%'、md: '60%'、lg: '50%'。 - 响应式取值——数组语法:数组按下标顺序映射到
[xs, sm, md, lg, xl],使用null可跳过某断点而不改变取值。 - 伪选择器与嵌套选择器:任何 CSS 选择器字符串都可作为键,支持
&:hover、&:active、&:focus-visible,也可定位 MUI 内部 slot 类名(如& .MuiButton-startIcon)、子元素(如& span)以及状态类(如&.Mui-disabled)。
styled() 函数
styled() 是经 MUI 主题与系统简写扩展的 Emotion styled 函数,用于创建可复用的具名组件。
- 基本用法:从
@mui/material/styles导入,包裹 Box 等组件,在回调中访问theme,并可结合theme.breakpoints.up('md')做断点覆盖。 - props 驱动样式:接受自定义 props 以生成条件样式,并用 TypeScript 泛型为其标注类型。
shouldForwardProp:对自定义布尔或字符串 props 应声明shouldForwardProp,避免非 HTML props 透传到 DOM 元素并引发 React 未知属性警告。- 扩展现有 styled 组件:可基于已有 styled 组件再次调用
styled()追加样式。
选型指南
资料给出的决策建议:
- 单个实例的一次性样式:
sxprop。 - 两个及以上实例复用相同样式:
styled()。 - 样式由自定义 props 驱动:
styled()配合shouldForwardProp。 - 全局覆盖某个 MUI 组件:主题的
components.MuiXxx.styleOverrides。 - 基于组件状态的动态样式:
sx回调或带 props 的styled()。 - 性能敏感、渲染频繁的列表:
styled()(样式只计算一次)。 - 快速原型或布局微调:
sxprop。
使用方式(性能注意事项)
当 sx 取值对象身份变化时,每次渲染都会生成新的类名。对于频繁渲染的组件(虚拟化列表、动画项),建议优先使用 styled() 或对 sx 对象做记忆化。资料给出对照写法:避免每次渲染新建对象字面量;可把静态部分抽到 styled() 基组件、sx 只保留动态部分;复杂动态 sx 可用 React.useMemo。
常见模式
- 暗色/浅色模式条件:通过
theme.palette.mode判断取值。 sx数组组合(MUI v5+):传入数组组合样式,假值条目会被跳过,可用于条件化高亮、禁用态等。- Container 内全出血区块:用
styled(Box)配合width: '100vw'、左右各-50vw外边距实现。
限制
系统简写别名仅在 sx(以及带系统工具的 styled)内有效,普通 Emotion 不支持。自定义 props 需配合 shouldForwardProp 防止透传到 DOM。sx 在渲染频繁场景存在重复生成类名的性能开销,需按上述方式优化。