【问题标题】:Condense multiple conditional statements into one switch in styled-components?将多个条件语句压缩为样式组件中的一个开关?
【发布时间】:2019-12-17 14:29:41
【问题描述】:

我想将许多预先存在的按钮 CSS 定义压缩到一个样式组件中。我通过使用条件扩展我的定义找到了积极的结果,但是我已经到了定义变得相当大的地步,我想知道是否有一种方法可以用某种switch 来浓缩我的定义将 CSS 抽象为返回的内容的语句?

用例: 我有一个自定义的<Button> 组件,它需要几个道具themetype,所以我的按钮示例如下:

<Button theme="primary" category="my-cat">Click me</Button>

themecategory 将分别采用 2 个不同的变量,所以到目前为止没有什么疯狂的想法......

到目前为止,我的定义已经变得臃肿:

export const Button = styled.a`
    background: lightgrey;
    // ... More standard stuff

    ${props => (props.theme === 'one' || props.theme === 'two') && `
        // ... more CSS
    `}

    ${props => (props.theme === 'one' && props.category === 'cat1') && `
        // ... more CSS
    `}

    ${props => (props.theme === 'one' && props.category === 'cat2') && `
        // ... more CSS
    `}
`;

是否有可能做一些事情,以便我可以将我的道具传递给一个函数并根据这些道具和条件操作返回添加的 CSS?比如:

function styleMyEl(props) {
    switch(props) {
        case (props.theme === 'one' || props.theme === 'two'):
            // return my additional css
        case ...
        default:
            return;
    }
}

export const Button = styled.a`
    background: lightgrey;
    // ... More standard stuff

    ${props => styleMyEl(props)}

【问题讨论】:

    标签: javascript css reactjs styled-components


    【解决方案1】:

    您可以尝试返回css 块:

    import React from 'react';
    import ReactDOM from 'react-dom';
    import styled, { css } from 'styled-components';
    
    function styleMyEl(theme) {
      switch (theme) {
        case 'one':
          return css`
            background: black;
            color: pink;
          `;
        default:
          return css`
            background: pink;
            color: black;
          `;
      }
    }
    
    export const Button = styled.a`
      ${props => styleMyEl(props.theme)}
    `;
    
    const App = () => {
      return (
        <>
          <div>
            <Button theme="one">Button</Button>
          </div>
          <div>
            <Button>Button</Button>
          </div>
        </>
      );
    };
    
    ReactDOM.render(<App />, document.getElementById('root'));
    


    这是一个常见问题,您可以查看尝试解决此问题的styled-map 库:

    仅使用样式化组件,您通常会执行以下操作:

    const Button = styled.button`
     color: ${props =>
       props.primary && '#0c0' ||
       props.warning && '#c00' ||
       props.info && '#0cc' ||
       '#ccc'
     };
     border: 2px solid ${props =>
       props.primary && '#0c0' ||
       props.warning && '#c00' ||
       props.info && '#0cc' ||
       '#ccc'
     };
     font-size: ${props =>
       props.small && '8px' ||
       props.medium && '18px' ||
       props.large && '32px' ||
       '16px'
     };
    `;
    
    <Button primary large>Submit</Button>
    

    这是使用 styled-map 的相同组件:

    import styledMap from 'styled-map';
    
    const buttonColor = styledMap`
      primary: #0c0;
      warning: #c00;
      info: #0cc;
      default: #ccc;
    `;
    
    const Button = styled.button`
      color: ${buttonColor};
      border: 2px solid ${buttonColor};
      font-size: ${styledMap`
        large: 32px;
        small: 8px;
        medium: 18px;
        default: 16px;
      `};
    `;
    
    <Button primary large>Submit</Button>
    

    你应该寻找相关的styled-components utilities或自己实现一个,更多的例子是styled-isstyled-by

    【讨论】:

    • 看起来很有趣,但我不确定在这种特定情况下它是否会让我的生活更轻松。我有很多条件要考虑,有些是嵌套的:-/
    • 啊,我喜欢它的样子。我只是在考虑如何扩展它以适应多种不同的道具......
    【解决方案2】:

    人为的示例,但最近我开始使用 mixin,我认为它对我组织样式组件代码有很大帮助。您可以通过这种方式在 styled-components 中使用 switch case。

    基本上,样式化组件使用模板字符串,因此无论您从代码返回什么,都将像在样式化组件中编写它们一样运行。

    定义混入

    const mixin = props => {
      switch (true) {
        case props.p1 === "black" && props.p2 === 3:
          return `border:3px solid black;`;
    
        case props.p1 === "red" && props.p2 === 5:
          return `border: 5px solid red;`;
    
        case props.p1 === "orange" && props.p2 === 15:
          return `border: 15px solid orange;`;
    
        default:
          return `border:1px solid red;`;
       }
    };
    

    然后在您的样式化组件中调用它:

    const SC = styled.div `
      ${mixin}
      width: 50px;
      height: 50px;
    `;
    

    并将其用作任何样式组件

    <SC p1="black" p2={3} />
    

    我创建了一个沙盒。看一下道具的日志: https://codesandbox.io/s/blue-hill-vyrq9

    【讨论】:

    • 我想这也可以和return css`...`一起使用
    猜你喜欢
    • 1970-01-01
    • 2012-08-14
    • 2019-12-31
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多