say*_*ode 27 javascript reactjs material-ui
MUI 组件中的 style 和 sx prop 几乎做同样的事情。sx 属性提供了一些简写语法,并允许您访问主题对象。但除此之外,它们看起来完全相同。你什么时候应该使用其中一种而不是另一种?
say*_*ode 41
要真正了解使用哪一个,我们需要了解幕后发生的情况。Material UI 使用情感(或您手动选择的任何样式引擎)来设置其组件的样式。从表面上看,以下两个似乎在做同样的事情:
<Box sx={{ height:'50px', width:'25px' }}/>
<div style={{ height:'50px', width:'25px' }}/>
Run Code Online (Sandbox Code Playgroud)
两者都将具有所需高度和宽度的 div 渲染到 DOM。但对于 div,样式以内联样式应用,而 Box 以类的形式将样式应用于 div 元素。类定义本身存储在 head 标记中,您可以检查该标记以查看以下内容

只要我们只声明一次样式,这一切都很好。但当你添加动态样式时,事情真的会变得疯狂。也许有一个状态变量控制你的 div 的高度。
function CustomComponent(){
const [computedHeight,setComputedHeight]=useState();
useEffect(()=>{
window.addEventListener('resize',()=>setComputedHeight(window.innerWidth/2))
},[]);
return (
<Box sx={{ height:computedHeight, width:'25px'}}/>
<div style={{ height:computedHeight, width:'25px'}}/>
)
Run Code Online (Sandbox Code Playgroud)
这是一种常见的情况,其中某些外部变量(例如浏览器窗口的宽度)决定了组件的某些属性。每当此状态更改为新值时,MUI 都会创建一个新类,将其设置为 Box 的类,并将定义添加到<head>您网站的标签中,作为一个全新的<style>标签。因此,在很短的时间内,head 标签就会填满数百个 style 标签,这显然是不可取的。
但是,对于 div 标签,样式位于内联。因此,无论值更改一次,还是一百次,样式都只有一个定义,并且它存在于元素本身上。无需担心。
编辑1:
MUI 仅为以前未使用过的样式创建新的样式标记。为了说明这一点,如果你的 sx prop 像这样动态地改变“红色”和“蓝色”之间的颜色,
sx={{
color: dynamicValue ? 'red' : 'blue',
}}
Run Code Online (Sandbox Code Playgroud)
color无论您更改dynamicValue 的值多少次,MUI 都只会创建两个标签(针对 的两个可能值)。MUI 将只使用旧样式标签。
关于伪选择器的注意事项:
另一件事需要注意的是,内联样式不能使用伪元素(如::after、 或::before)或伪类(如:hover等:focus),因为内联样式直接影响当前元素。您必须采用像 css 变量这样的解决方法才能更改伪元素/类的样式。
太长了;将动态样式(根据某些变量更改的样式)放在 style 属性中,并将所有静态样式放在 sx 属性中
San*_*ath 10
style与sxMUI 5 中的比较
sxprop 仅适用于 MUI 组件Grid,例如Box、 等,而styleprop 则适用于 MUI 组件和类似 HTML 的元素 (JSX),例如、span等。articleh1
sx在某些情况下,与 prop 相比,prop 非常有用style,如下所述。它们之间可能存在很多差异,但这是我注意到的 3 个关键差异,您可能会经常遇到它们。
theme参数(获取调色板),sx这是我们不能style这样做的 -color: (theme) => theme.palette.primary.main1. 定义媒体查询
style和sx最流行的一个区别是,基于 Material UI 主题定义媒体查询。
您将如何处理styleprop 中的媒体查询?您可以使用自己的断点并按照 CSS 中的方式进行操作,但不能使用 Material UI 断点。
这就是sxprop 派上用场的地方,您可以定义媒体查询和其他 MUI 提供的属性来改变您的样式。
例子
import { Typography, createTheme, ThemeProvider } from '@mui/material'
let theme = createTheme()
function Demo() {
const stylePropCSS = {
backgroundColor: 'lightblue',
/* theme prop is not understood here,
so this breakpoint will not work,
and text will not turn into orange */
[theme.breakpoints.down('xl')]: {
backgroundColor: 'orange',
},
}
/* theme prop is understood here.
breakpoints can be applied here based on MUI theme
*/
const sxPropCSS = {
backgroundColor: 'lightgreen',
[theme.breakpoints.up('xs')]: {
backgroundColor: 'orange',
},
}
return (
<ThemeProvider theme={theme}>
{/* style prop */}
<Typography style={stylePropCSS}>
This text will <b>NOT TURN</b> orange as
I am using style prop and MUI 'theme' is not understood
</Typography>
<br />
{/* sx prop */}
<Typography sx={sxPropCSS}>
This text will <b>TURN</b> into orange as
I am using sx prop and MUI 'theme' is understood
</Typography>
</ThemeProvider>
)
}
export default Demo
Run Code Online (Sandbox Code Playgroud)
2. 嵌套样式并在 sx prop 中使用主题
使用 prop 时可以嵌套样式sx,但使用 prop 时不能这样做style。
带有 sx 道具
<Box sx={styles.post}>
<Typography variant="h4">This is the title</Typography>
</Box>
Run Code Online (Sandbox Code Playgroud)
Box是div背景黑色,我需要h4是黄色或MUI primary color。sx有了这个要求,当我使用这样的 prop时,我可以嵌套我的样式,将其放置h4在内部post并sx仅定义Box
const styles = {
post: {
backgroundColor: 'black',
// nesting h4 inside post
h4: {
// color:'yellow' // OR
color: (theme) => theme.palette.primary.main,
/* I cannot use theme inside style object. Since I am going
to apply styles.post to sx prop,I could make use of theme
object here as an argument */
},
},
}
Run Code Online (Sandbox Code Playgroud)
带有风格道具
<Box style={styles.post}>
<Typography variant="h4" style={style.heading}>
This is the title
</Typography>
</Box>
const styles = {
post: {
backgroundColor: 'black',
},
// I can't nest the heading inside post, so defining it outside post
heading: {
color: 'yellow',
// color: (theme) => theme.palette.primary.main, // THIS WON'T WORK with style prop
},
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22101 次 |
| 最近记录: |