如何通过 props 动态改变组件中使用的样式?

问题描述 投票:0回答:1

我正在尝试重构一些 css 以使用样式化组件,这样我就可以部署云组件并声明其大小样式以及它通过道具使用的动画样式,因此它看起来像这样:

<Cloud size={TinyCloud} animation={cloud_1}/>

我有一个定义云的基本样式:

const Cloud = styled(css)`
  -webkit-animation: clouds 60s infinite linear;
  -moz-animation: clouds 60s infinite linear;
  -ms-animation: clouds 60s infinite linear;
  -o-animation: clouds 60s infinite linear;
  animation: clouds 60s infinite linear;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;
  border-radius: 10px;
  position: relative;
  margin: 20px 20px 10px 2050px;
  width: 54px;
  height: 5px;
  background: black;
  & div {
    -moz-box-shadow: inset -2px -3px 0 0 #f7e7eb;
    -webkit-box-shadow: inset -2px -3px 0 0 #f7e7eb;
    box-shadow: inset -2px -3px 0 0 #f7e7eb;
    position: absolute;
    border-radius: 50%;
    width: 12px;
    height: 12px;
    left: -3px;
    bottom: 0;
    background: #fafbf0;
    z-index: 10;
  }
  & div:first-child + div {
    -moz-transform: scale(1.6, 1.6);
    -ms-transform: scale(1.6, 1.6);
    -webkit-transform: scale(1.6, 1.6);
    transform: scale(1.6, 1.6);
    margin: 0 0 4px 13px;
    z-index: 9;
  }
  & div:first-child + div + div {
    -moz-transform: scale(2.4, 2.4);
    -ms-transform: scale(2.4, 2.4);
    -webkit-transform: scale(2.4, 2.4);
    transform: scale(2.4, 2.4);
    margin: 0 0 9px 32px;
    z-index: 8;
  }
  & div:first-child + div + div + div {
    -moz-transform: scale(1.3, 1.3);
    -ms-transform: scale(1.3, 1.3);
    -webkit-transform: scale(1.3, 1.3);
    transform: scale(1.3, 1.3);
    margin: 0 0 2px 50px;
    z-index: 7;
  }
  @-webkit-keyframes clouds {
    0% {
        left: -50%;
    }
    100% {
        left: 20%;
    }
  }
  @-moz-keyframes clouds {
    0% {
        left: -50%;
    }
    100% {
        left: 20%;
    }
  }
  @-ms-keyframes clouds {
    0% {
        left: -50%;
    }
    100% {
        left: 20%;
    }
  }
  @keyframes clouds {
    0% {
        left: -50%;
    }
    100% {
        left: 20%;
    }
  }
`;

此样式然后由另外四种样式扩展:

const TinyCloud = styled(Cloud)`
  -moz-transform: scale(0.35);
  -ms-transform: scale(0.35);
  -webkit-transform: scale(0.35);
  transform: scale(0.35);
`;

我还有 12 种更多样式来扩展现在样式化的基础云(现在是 TinyCloud):

const cloud_1 = styled(css)`
  -webkit-animation-duration: 10s;
  -moz-animation-duration:    10s;
  -ms-animation-duration:     10s;
  -o-animation-duration:      10s;
  animation-duration:         10s;
  margin-left: 40%;
`;

尺寸和动画在单独的文件中并导出,因此它们可以作为道具传递。

我试过的是这样定义的(我知道我不能这样做,但我把它包括在内以表明我的想法):

const Cloud = (size, animation) => {
  const CloudFrame = styled(size)`
  ${animation}
  `
  return (
    <CloudFrame>
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </CloudFrame>
  )
};

而不是像这样使用类:

<div class="cloud tiny cloud-4">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>
reactjs styled-components
1个回答
0
投票

使用样式化组件,通常的每个实例定制使用基于道具的自适应

除非您的尺寸和云 ID 自定义比您的示例更复杂,否则您可以轻松使用此适配技术:

const CloudFrame = styled.div`
  animation: clouds 60s infinite linear;
  // etc.

  transform: scale(${props => props.scale});

  animation-duration: ${props => props.duration};
  margin-left: ${props => props.left};
`;

// Usage
function App() {
  return (
    <CloudFrame scale={0.35} duration="10s" left="40%">
      <div></div>
      <div></div>
      <div></div>
      <div></div>
    </CloudFrame>
  )
}

有了这个,您甚至不需要预定义硬编码的大小和云 ID 集:您可以在实例化组件时任意定义这些值。

© www.soinside.com 2019 - 2024. All rights reserved.