【问题标题】:Handling Combinations of Props in Styled Components处理样式化组件中的道具组合
【发布时间】:2019-10-01 19:09:33
【问题描述】:

我正在尝试使用样式组件来实现基于材质设计的按钮组件。该组件将有许多道具(例如大小、图标、浮动等)。

不过,管理各种道具组合变得相当困难。

例如,按钮有三种尺寸:默认、小和大。

但是小按钮的大小会根据它是普通按钮还是浮动按钮而变化。大按钮也是如此。

所以我有以下尺寸:

  • 小浮动
  • 默认
  • 浮动
  • 大浮动

当然,我还有其他未列出的组合。

因此,我的代码开始变得有点复杂,因为我不仅要检查是否存在某个道具 (${props => { if (props.floating)...),还要检查该特定道具是否与另一个道具结合存在(${props => { if (props.floating && props.small)...)。

因此,我想知道是否有人对在处理大量组合时如何最好地组织和构造道具有任何建议?

谢谢。

【问题讨论】:

    标签: javascript reactjs styled-components css-in-js


    【解决方案1】:

    请记住,您可以在实例化中进行解构。比如你可以这样写:

    ${({ floating, small }) => {
        if (floating && small){
        ...
        }
    }
    

    它会减少一些膨胀。

    【讨论】:

    • 是的(而且比我现在做的要好)。但它仍然有很多 if/else 语句——我想知道我是否缺少更优雅的东西)。
    【解决方案2】:

    我更喜欢将我的 css 分开,就像在 styles.js 文件中一样。以下面的代码为例。它使 css 井井有条,并使不同选项的实现变得非常干净。当然,将您的 css 添加到适当的定义中

    //styles.js
    import { css } from 'styled-components';
    
    export const buttonbase = css`/*base styles for all buttons*/`;
    export const small = css`/*small size styles*/`;
    export const medium = css`/*default size styles*/`;
    export const large = css`/*large size styles*/`;
    export const floating = css`/*float styles*/`;
    

    在你的组件文件中:

    //Button.js
    import React from 'react';
    import PropTypes from 'prop-types';
    import styled from 'styled-components';
    import * as Styles from './styles';
    
    const propTypes = {
      floating: PropTypes.bool,
      size: PropTypes.oneOf(['small', 'medium', 'large']),
      children: PropTypes.node,
    };
    
    const defaultProps = {
      floating: false,
      size: 'medium',
    };
    
    const ButtonBase = styled.button`
      ${Styles.buttonbase};
      ${props => (props.floating ? Styles.floating : '')};
      ${props => Styles[props.size]};
    `;
    
    const Button = ({ floating, size, children, ...rest }) => (
      <ButtonBase
        size={size}
        floating={floating}
        {...rest}
      >
        {children}
      </ButtonBase>
    );
    
    Button.propTypes = propTypes;
    Button.defaultProps = defaultProps;
    
    export default Button;
    

    如果给定这些值,结果将是:

    export const buttonbase = css`
      border: 1px solid black;
      padding: 10px;
    `;
    export const medium = css`
      font-size: 16px;
      height: 30px;
    `;
    export const floating = css`
      float: left;
    `;
    

    还有这个组件:

    <Button size="medium" floating />
    

    &lt;ButtonBase/&gt; 组件将导入的样式中的buttonbasemediumfloating 组合在一起,生成完整的样式:

      border: 1px solid black;
      padding: 10px;
      font-size: 16px;
      height: 30px;
      float: left;
    

    【讨论】:

    • 我喜欢这个系统的组织,但我想知道它如何与各种组合一起工作。我可以看到如何轻松设置大小或确定按钮是否为浮动按钮,但是如何将大小与浮动按钮结合起来?
    • @Moshe 假设大小只设置大小,浮动不改变大小,&lt;ButtonBase/&gt; 组件正在合并导入的样式。我将在答案中添加一个简短的解释...
    • 在我的例子中,常规按钮有一种尺寸,浮动按钮有不同的尺寸。因此,例如,在您上面的示例中:常规介质将是 font-size: 16px; height: 30px; 而浮动介质可能是 font-size: 18px; height: 36px; 我想知道您的系统将如何处理?
    • @Moshe 如果没有看到这些变量的完整定义,我很难说。我尝试将职责分开,因此只有 size 道具会改变大小。我对这个组件的实现还包括许多其他道具,但每个道具在语义上都与其功能相关。
    • 好的 - 有道理。对我来说,一种可能的解决方案可能是制作一个单独的 FloatingButton - 使用它自己的尺寸道具。明天我会试验一下,看看什么效果最好。不管怎样,感谢您的帮助——我喜欢分离职责的想法。
    【解决方案3】:

    我使用一个名为 styled-is 的包来帮助设置样式组件的样式,它附带了您可以直接与样式组件一起使用的辅助函数。

    【讨论】:

    • 这很整洁。感谢分享。
    猜你喜欢
    • 2019-10-31
    • 2018-05-18
    • 1970-01-01
    • 2021-03-04
    • 2021-08-27
    • 2021-09-15
    • 2021-08-24
    • 2021-09-18
    • 2019-09-26
    相关资源
    最近更新 更多