javascript – Emotion CSS-in-JS – 如何基于组件道具添加条件CSS?

我想要一个用Emotion设计的组件,它采用最终控制造型的道具.例如,考虑一个GridCol组件,它具有各种改变填充和宽度的道具(宽度可以在不同的视口宽度上改变).

我想使用这样的API:

<GridCol gutter size="2>

// or alternatively, like this:

<GridCol gutter size={{
  m: 2,
  l: 4
}}>

这里发生了三件事:

>装订线是一个布尔道具,可以为列添加一些水平填充
> size prop可以是字符串或对象.如果它是一个字符串,我们只是添加几行CSS并且我们很好,但是,如果它是一个对象,我们需要根据在别处设置的断点对象插入一些媒体查询.

Emotion’s docs不清楚如何处理这种性质的造型,至少我还没有看到它,所以我希望找到一个共同的解决方案.

对于天沟道具,它是微不足道的:

const GridCol = props => styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props.gutter ? `0 10px` : '0'};
`

对于大小的道具,它变得更复杂,我希望得到的CSS看起来像这样:

const GridCol = props => styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props.gutter ? `0 10px` : '0'};

  /* styles here if  `size` is a string */
  width: 10%;

  /* styles here if  `size` is an object */
  @media screen and (min-width: 500px) {
      width: 20%;
  }


  @media screen and (min-width: 800px) {
      width: 30%;
  }


  @media screen and (min-width: 1100px) {
      width: 40%;
  }
`

宽度值将由prop的键确定,该键对应于断点对象中的值,这部分不是微不足道的,但我不知道如何动态生成所需的css.

我确信我可以添加更多信息,我已经做了一些尝试,但目前还没有任何工作.我的感觉是我应该创建一个无状态功能组件,为每个条件生成css,然后在最后加入CSS.

解决方法:

这是一个很好的问题.首先,避免这种模式.

const GridCol = props => styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props.gutter ? `0 10px` : '0'};
`

在此示例中,在每个渲染上创建一个新的样式化组件,这对于性能很糟糕.

任何表达式或插值都可以是一个函数.此函数将接收2个参数:props和context

const GridCol = styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props => props.gutter ? `0 10px` : '0'};
`

至于你的例子中的大小支柱,我将使用以下模式.

import { css } from 'emotion'

const sizePartial = (props) => typeof props.size === 'string' ?
  css`width: 10%;` :
  css`
   @media screen and (min-width: 500px) {
      width: 20%;
   }


   @media screen and (min-width: 800px) {
      width: 30%;
   }


   @media screen and (min-width: 1100px) {
      width: 40%;
   }
 `

然后,您可以像表达式中出现的任何其他函数一样使用partial.

const GridCol = styled('div')`
  display: block;
  box-sizing: border-box;
  flex: 1 0 0;
  min-width: 0;
  padding: ${props => props.gutter ? `0 10px` : '0'};
  ${sizePartial};
`

这是一个非常强大的模式,可用于组合项目中可重用的动态样式.

如果您对利用此模式的其他库感兴趣,请查看
https://github.com/emotion-js/facepainthttps://github.com/jxnblk/styled-system

上一篇:安装Percona版本的MySQL主从复制


下一篇:数据库的数据结构(2)——什么是SSTable.md