【问题标题】:Material UI responsive based on element sizeMaterial UI 响应基于元素大小
【发布时间】:2019-07-30 06:39:41
【问题描述】:

我正在使用 React 和 MaterialUI 构建一个系统,该系统将在另一个(不是基于 React 的)网站中显示小部件。我想让小部件响应,但它们需要响应自己的容器宽度而不是窗口宽度,因为我不知道小部件将占用多少页面。

我考虑过的选项:

  • 按时间间隔轮询容器大小
  • 根据窗口调整大小事件轮询容器大小
  • 在启动时根据容器和窗口大小设置主题断点

这些对我来说似乎都是相当丑陋的解决方案。有没有一种优雅的方式来做我想做的事?

【问题讨论】:

    标签: reactjs widget material-ui responsive


    【解决方案1】:

    您可以监听组件大小的变化,而不是断点。您可以使用react-use hook useMeasure 来实现(它依赖于所有主流浏览器都支持的ResizeObserver),如下例所示:

    /** @jsx jsx */
    import { css, jsx } from '@emotion/core';
    import { faAddressBook, faCoffee } from '@fortawesome/free-solid-svg-icons';
    import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
    import { useMeasure } from 'react-use';
    
    const useMyComponentStyle = (params) => {
        const { color } = params;
        const [ref, { width }] = useMeasure();
    
        const borderColor = width < 150 ? 'red' : width < 400 ? 'yellow' : 'green';
        const icon = width < 250 ? faCoffee : faAddressBook;
    
        const style = css`
            color: ${color};
            padding: 10px;
            border: 1px solid ${borderColor};
        `;
    
        return {
            ref,
            style,
            icon,
            width,
        };
    };
    
    export const MyComponent = (props) => {
        const { ref, style, icon, width } = useMyComponentStyle(props);
    
        return (
            <div ref={ref} css={style}>
                <FontAwesomeIcon icon={icon} />
                {props.children} [[{parseInt('' + width)}px]]
            </div>
        );
    };
    
    const containerStyle = css`
        padding: 100px 200px;
        border: 1px solid blue;
    `;
    
    export const MyContainer = () => (
        <div css={containerStyle}>
            <MyComponent color='blue'></MyComponent>
        </div>
    );
    
    ReactDOM.render(<MyContainer />, document.getElementById('root'));
    

    上面的例子使用emotion作为css样式,但是样式可以使用另一个库来定义,比如jssstyled components,甚至是简单的react内联样式。

    组件 MyComponent 包含在容器组件 MyContainer 中,该容器组件具有左右 padding 的值 200px,并且您可以在调整浏览器视图的大小时看到 border 颜色为 @987654333 @ 基于组件本身的大小(如果组件的宽度小于150px,则red,如果小于400px,则yellow,否则为green ),而不是基于窗口的大小。

    【讨论】:

      【解决方案2】:

      要使各种@material-ui/core 元素占用的空间与放置它们的容器一样多,我会使用Grid 组件。

      我用过以下:

      <Grid container spacing={24}>
        <Grid item>
          Your content here
        </Grid>
      </Grid>
      

      如果您进一步希望您的网格项目能够响应屏幕大小等内容,您可以这样做:

      const grid = {
          xs: 24,
          sm: 24,
          md: 24,
          lg: 12,
          xl: 12,
      };
      

      <Grid item {...grid}>
      

      文档:https://material-ui.com/layout/grid/

      【讨论】:

      • 谢谢,但这不是我的意思。问题是断点(在您的示例中,网格项将从 24 列更改为 12 列)指的是浏览器的实际窗口大小,而不是我的小部件的容器大小。
      • @MartenJacobs 您找到适合您的解决方案了吗?我也有同样的需求
      猜你喜欢
      • 1970-01-01
      • 2022-11-09
      • 1970-01-01
      • 1970-01-01
      • 2020-03-31
      • 2020-11-19
      • 2015-10-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多