繁体   English   中英

有没有更好的方法来根据反应应用程序的屏幕大小更改样式?

[英]Is there a better way to change style based on screen size on react app?

我在我的反应应用程序上使用 Material UI,我正在使用来自 mui 的 useMediaQuery 和 useTheme。 这是我现在拥有的代码。 有没有更好的方法来优化更少的代码? 两个代码之间只有少数样式更改。

const MainPage = () => {
    const theme = useTheme();
    const isMatch = useMediaQuery(theme.breakpoints.down('md'))
    return (
        <div className='mainPage'>
            {
                isMatch ? (
                    <>
                        <Box sx={{ display: "flex", justifyContent: "center", alignContent: "center", flexDirection: "column", padding: "60px 10px 10px 10px" }}>
                            <Box component="img" src={LandingImage} sx={{ width: "100%" }} />
                            <Box sx={{ paddingTop: 8 }}>
                                <Typography sx={{ fontSize: 26, fontWeight: "bold", fontFamily: "sans-serif", textAlign: "center", paddingBottom: 5 }}>About us</Typography>
                            </Box>
                        </Box>
                    </>
                ) : (
                    <>
                        <Box sx={{ display: "flex", justifyContent: "center", alignContent: "center", flexDirection: "row", paddingTop: 20 }}>
                            <Box component="img" src={LandingImage} />
                            <Box sx={{ width: 700, paddingTop: 8 }}>
                                <Typography sx={{ fontSize: 30, fontWeight: "bold", fontFamily: "sans-serif", textAlign: "center", paddingBottom: 5 }}>About us</Typography>
                            </Box>
                        </Box>
                    </>
                )}
        </div>
    )
}

由于移动/桌面 JSX 的结构是相同的,您可以删除这两个 JSX 模板中的一个,基于isMatch构建一个变量来存储组件配置,并将此变量传递给组件模板。


const MainPage = () => {
    const theme = useTheme();
    const isMatch = useMediaQuery(theme.breakpoints.down('md'))

    // Subset of props, to illustrate the idea.
    const config = isMatch ? {fontSize: 26} : {fontSize: 30};

    // Here only root <Box/> is configured, but you can configure all the nested components the same way.
    return (
        <div className='mainPage'>
          <Box sx={config}>[...]</Box>
        </div>
    )
}

(与嵌套在<Box/>中的组件相同 - 想法相同 - 根据您的状态声明一些具有值的变量并将它们传递给 JSX 声明)

确实不需要像这样进行媒体查询,因为sx属性提供了每个断点的自定义,如果你想要的话。

例如,请注意第一个 Box 组件上的flexDirection样式。 直到md断点的所有内容都获取column ,然后变为row

const MainPage = () => {
  const theme = useTheme();
  return (
    <div className='mainPage'>
      <Box sx={{ 
        display: "flex", 
        justifyContent: "center", 
        alignContent: "center", 
        flexDirection: { xs: "column", md: "row" },
        padding: { xs: "60px 10px 10px 10px", md: "20px 0 0 0" } 
      }}>
        <Box 
          component="img" 
          src={LandingImage} 
          sx={{ 
            width: { xs: "100%", md: 'unset' }
        }}/>
        <Box sx={{ 
          paddingTop: 8,
          width: { md: 700 }
        }}>
          <Typography 
            sx={{ 
              fontSize: { xs: 26, md: 30 }, 
              fontWeight: "bold", 
              fontFamily: "sans-serif", 
              textAlign: "center", 
              paddingBottom: 5 
          }}>
            About us
          </Typography>
        </Box>
      </Box>
    </div>
  )
}

https://mui.com/system/basics/#responsive-values

有几种选择。 首先是在 javascript 中创建一个样式对象,它可以像普通的 javascript 一样进行交互。 您已经在线执行此操作,但如果我们在上面的代码中执行此操作,我们可以使其动态化。

const myOuterBoxStyle = {
  display: "flex", 
  justifyContent: "center", 
  alignContent: "center",
  flexDirection: "row",
  paddingTop: 20
}
if (isMatch) {
  myOuterBoxStyle.flexDirection = "column";
  myOuterBoxStyle.paddingTop = undefined;
  myOuterBoxStyle.padding = "60px 10px 10px 10px";
}

一旦你完成了你需要的所有动态样式,你可以为你的组件做一个单一的回报,然后简单地把

<Box sx={{myOuterBoxStyle}}>

另一种选择是制作一个单独的 CSS 表并导入它,然后使用类。 就像是

.outer-box {
display: "flex";
justify-content: "center";
align-content: "center";
}

.is-match {
flex-direction: "column";
padding: "60px 10px 10px 10px"
}

然后您可以添加is-match类,或者可能添加is-not-match类,具体取决于。

最后一种选择是使用第三方包,它可以为您完成大部分工作,例如Tailwind

Mui 有断点简写语法,你可以在这里查看

因此,例如,您的代码也适用于:

const MainPage = () => {
  return (
    <div className="mainPage">
      <Box
        sx={{
          display: "flex",
          justifyContent: "center",
          alignContent: "center",
          flexDirection: ["column", "column", "row"],
          paddingTop: ["60px 10px 10px 10px", "60px 10px 10px 10px", 20]
        }}
      >
        <Box component="img" />
        <Box sx={{ width: ["unset", "unset", 700], paddingTop: 8 }}>
          <Typography
            sx={{
              fontSize: [26, 26, 30],
              fontWeight: "bold",
              fontFamily: "sans-serif",
              textAlign: "center",
              paddingBottom: 5
            }}
          >
            About us
          </Typography>
        </Box>
      </Box>
    </div>
  );
};    

在上面的示例中,我使用断点作为数组, mui文档说:

第二个选项是将断点定义为一个数组,从最小到最大的断点。

所以想象数组位置是: [xs, sm, md, lg, xl]并且断点等同于theme.breakpoints.up

另一种方法是使用断点作为对象:

简单的例子

<Box
   sx={{
      width: {
         xs: 100, // theme.breakpoints.up('xs')
         sm: 200, // theme.breakpoints.up('sm')
         md: 300, // theme.breakpoints.up('md')
         lg: 400, // theme.breakpoints.up('lg')
         xl: 500, // theme.breakpoints.up('xl')
      },
   }}
>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM