簡體   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