如何根据设备尺寸渲染不同的组件?

How to render different components based off device size?

我希望构建一个断点为 1024 的响应式应用程序。 当用户登录 in/signs 时,将有几个问题需要回答。

在移动设备上,这将在屏幕上一次呈现为一个问题。然后,用户将看到一个滑动过渡屏幕,将他们移至下一个问题。

一旦超过断点,所有问题将同时呈现在屏幕上。

有谁知道是否有任何样式框架可以处理类似的东西,或者是否有任何基于像素宽度的条件渲染的变通方法?

这将是一个基于 React 的应用程序。目前使用基础造型。

谢谢!!

你看过bootstrap了吗? bootstrap 4 都有反应库:https://reactstrap.github.io/ and bootstrap 3: https://react-bootstrap.github.io/

您可以使用 CSS 设置 display: none 的媒体查询来为不同的尺寸创建断点。或者你可以使用 React Responsive library 来渲染基于媒体查询的 React 组件。

css 媒体查询示例(将其插入 .css 文件并将其包含到您的应用程序中):

//Any device with className .loginFeature below 1024px will not be displayed
@media (max-width: 1024px) {
  .loginFeature:{
    display: none;
  }
}

React 响应示例:

<MediaQuery query="(max-device-width: 1024px)">
  //Insert any components/html here that you want rendered thats below 1024px
</MediaQuery>

对于台式机

@media only screen and (min-width: 768px) {
    /* For desktop: */
    .col-1 {width: 8.33%;}
    .col-2 {width: 16.66%;}
    .col-3 {width: 25%;}
    .col-4 {width: 33.33%;}
    .col-5 {width: 41.66%;}
    .col-6 {width: 50%;}
    .col-7 {width: 58.33%;}
    .col-8 {width: 66.66%;}
    .col-9 {width: 75%;}
    .col-10 {width: 83.33%;}
    .col-11 {width: 91.66%;}
    .col-12 {width: 100%;}
}

对于手机和平板电脑

/* Smartphones (portrait and landscape) ----------- */
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) {
/* Styles */
}

/* Smartphones (landscape) ----------- */
@media only screen and (min-width : 321px) {
/* Styles */
}

/* Smartphones (portrait) ----------- */
@media only screen and (max-width : 320px) {
/* Styles */
}

/* iPads (portrait and landscape) ----------- */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) {
/* Styles */
}

/* iPads (landscape) ----------- */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) {
/* Styles */
}

/* iPads (portrait) ----------- */
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) {
/* Styles */
}

/**********
iPad 3
**********/
@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : landscape) and (-webkit-min-device-pixel-ratio : 2) {
/* Styles */
}

@media only screen and (min-device-width : 768px) and (max-device-width : 1024px) and (orientation : portrait) and (-webkit-min-device-pixel-ratio : 2) {
/* Styles */
}
/* Desktops and laptops ----------- */
@media only screen  and (min-width : 1224px) {
/* Styles */
}

/* Large screens ----------- */
@media only screen  and (min-width : 1824px) {
/* Styles */
}

/* iPhone 4 ----------- */
@media only screen and (min-device-width : 320px) and (max-device-width : 480px) and (orientation : landscape) and (-webkit-min-device-pixel-ratio : 2) {
/* Styles */
}

@media only screen and (min-device-width : 320px) and (max-device-width : 480px) and (orientation : portrait) and (-webkit-min-device-pixel-ratio : 2) {
/* Styles */
}

/* iPhone 5 ----------- */
@media only screen and (min-device-width: 320px) and (max-device-height: 568px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){
/* Styles */
}

@media only screen and (min-device-width: 320px) and (max-device-height: 568px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){
/* Styles */
}

/* iPhone 6 ----------- */
@media only screen and (min-device-width: 375px) and (max-device-height: 667px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){
/* Styles */
}

@media only screen and (min-device-width: 375px) and (max-device-height: 667px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){
/* Styles */
}

/* iPhone 6+ ----------- */
@media only screen and (min-device-width: 414px) and (max-device-height: 736px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){
/* Styles */
}

@media only screen and (min-device-width: 414px) and (max-device-height: 736px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){
/* Styles */
}

/* Samsung Galaxy S3 ----------- */
@media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 2){
/* Styles */
}

@media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 2){
/* Styles */
}

/* Samsung Galaxy S4 ----------- */
@media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 3){
/* Styles */
}

@media only screen and (min-device-width: 320px) and (max-device-height: 640px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 3){
/* Styles */
}

/* Samsung Galaxy S5 ----------- */
@media only screen and (min-device-width: 360px) and (max-device-height: 640px) and (orientation : landscape) and (-webkit-device-pixel-ratio: 3){
/* Styles */
}

@media only screen and (min-device-width: 360px) and (max-device-height: 640px) and (orientation : portrait) and (-webkit-device-pixel-ratio: 3){
/* Styles */
}

对于你的 React 项目,请查看 react-responsive。使用它来导入一个名为 MediaQuery 的组件。 MediaQuery 只会在满足您为其设置的条件时渲染其子组件。

要安装:

yarn add react-responsive

将此行添加到您的项目以导入 MediaQuery:

import MediaQuery from "react-responsive";

然后使用 MediaQuery 有条件地呈现您的内容或您的问题:

<MediaQuery query=(min-width: 1024px)>
    <div className="question">
        ...
    </div>
</MediaQuery>

您可以找到有关反应响应的更多信息here

如果您在 React 应用程序中使用 Material UI 作为样式库,则可以通过两种方法实现。

因此,在解释方法之前,我将快速解释 6 个术语,这些术语是使用 Material UI 设计响应式设计的基础

他们是——xs,sm,md,lg,xl顾名思义, xs - xtra small、sm - small、md - medium、lg - large 和 xl - xtra large,这些只是设备尺寸的断点变量。

范围从 0 - 1920 像素,其中每个断点表示小于其绝对值的值。

因此,sm = 600px,则表示从0 - 600 的所有设备都属于sm 类别,此概念适用于其他断点变量。 Check this out

因此,您可以在 Grid 或 Container 中使用它,它会相应地进行调整。 您也可以在 Material UIi 组件的样式中使用它。 例如 -

const styles = (theme) => ({
  root: {
    padding: theme.spacing(1),
    [theme.breakpoints.down('md')]: {
      backgroundColor: theme.palette.secondary.main,
    },
    [theme.breakpoints.up('md')]: {
      backgroundColor: theme.palette.primary.main,
    },
    [theme.breakpoints.up('lg')]: {
      backgroundColor: green[500],
    },
  },
});

因此,从 xs 到 md 的所有尺寸将具有辅助色,从 md 到 lg 将具有原色,并且大于 lg 的设备尺寸将具有绿色。

您可以尝试并针对多种条件样式执行此操作以实现响应式设计。

如果你想渲染一个完全不同的组件,那么你可以使用 Material UI 提供的 useMediaQuery 钩子。

例如-

import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';

function MyComponent() {
  const theme = useTheme();
  const matches = useMediaQuery(theme.breakpoints.up('sm'));

  return <span>{`theme.breakpoints.up('sm') matches: ${matches}`}</span>;
}

此处,如果设备大小匹配sm - xl 的断点,则匹配常量将为真,如果小于sm,则为假。

钩子return一个布尔值,我们传给它一个断点。

总而言之,我发现这两个简单的方法对于设计响应式屏幕非常有用。