React Styled组件:如何基于道具添加CSS样式?

时间:2018-12-31 14:08:14

标签: javascript reactjs

我一直在寻找解决问题的方法。 我在自己的文件中有几个标题标签(H1,H2等)。 我想在基于prop调用它们时添加一些CSS。有些标题底端有一个小边框,有些则没有。因此,为了修改我的代码,我想添加一个基于prop的CSS。我似乎找不到办法。

这是标题H2的示例:

import styled from 'styled-components';
import colors from '../../../../colors'; 
import fonts from '../../../../fonts';
import fontWeights from '../../../../fontWeights';

const HeadingH2 = styled.h2`
  color: ${colors.text};
  font-family: ${fonts.montSerrat};
  font-size: 1.6em;
  font-weight: ${fontWeights.light};
  letter-spacing: 0.2em;
  padding-bottom: 0.7em;
  position: relative;
  text-transform: uppercase;
  text-align: center;
  &:after{
    content: "";
    display: block;
    height: 3px;
    width: 45px;
    background-color: currentColor;
    /* position */
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  }
`;

export default HeadingH2

调用标题H2的示例:

import React from 'react';
import HeadingH2 from '../../common/headings/heading_h2';
import HeadingBaseline from '../../common/headings_baseline';


// Features
import {SectionContainer, FeaturesContainer} from './features.style';

import Feature from './feature';
import feature1 from '../../../img/features/feature1.png';
import feature2 from '../../../img/features/feature2.png';
import feature3 from '../../../img/features/feature3.png';

// Text
import Text from '../../../content';

const Features = () => {
  return(
    <SectionContainer id={"what"}>
      <HeadingH2>
        What We Do
      </HeadingH2>
    <HeadingBaseline>
      {Text.headingBaseline}
    </HeadingBaseline>
  <FeaturesContainer>
    <Feature 
      src={feature1} 
      headingText={Text.feature1.heading}
      paragraph={Text.feature1.paragraph}
      />
    <Feature 
      src={feature2} 
      headingText={Text.feature2.heading}
      paragraph={Text.feature2.paragraph}
      />
    <Feature 
      src={feature3} 
      headingText={Text.feature3.heading}
      paragraph={Text.feature3.paragraph}
      />
  </FeaturesContainer>
</SectionContainer>
)
};

export default Features;

我要提取以下CSS属性

position: relative;
text-transform: uppercase;
text-align: center;
&:after{
 content: "";
 display: block;
 height: 3px;
 width: 45px;
 background-color: currentColor;
 /* position */
 position: absolute;
 bottom: 0;
 left: 50%;
 transform: translateX(-50%);

因此,假设我在单独的文件中具有上述CSS规则,那么如何在样式组件HeadingH2上使用道具添加/导入它们。

感谢您的帮助:)

5 个答案:

答案 0 :(得分:2)

类似的作品:

const HeadingH2 = styled.h2`
  position: ${props => props.relative && 'relative'};
  padding: ${props => props.paddingBottom ? '0 0 20px 0' : '0'};
}
`;

然后这样使用:

<HeadingH2 relative paddingBottom />

答案 1 :(得分:0)

为什么不仅仅拥有headingLevel道具?然后将其传递给样式化组件?并且只有一个StyledHeader样式的组件,因为我猜代码在所有标题样式文件中都基本相同?很大,不,您要始终尝试不重复代码。

const Features = () => {
  return(
    <SectionContainer id={"what"}>
      <StyledHeader
        headingLevel={headingLevel}
      >
        What We Do
      </StyledHeader>
    <HeadingBaseline>
      {Text.headingBaseline}
    </HeadingBaseline>
  <FeaturesContainer>
    <Feature 
      src={feature1} 
      headingText={Text.feature1.heading}
      paragraph={Text.feature1.paragraph}
      />
    <Feature 
      src={feature2} 
      headingText={Text.feature2.heading}
      paragraph={Text.feature2.paragraph}
      />
    <Feature 
      src={feature3} 
      headingText={Text.feature3.heading}
      paragraph={Text.feature3.paragraph}
      />
  </FeaturesContainer>
</SectionContainer>
)
};

export default Features;

在您的StyledHeader文件中

下面的函数将采用您传入的标题级别h1h2h3并应用边框,如果不是上面的3个标题级别,它将为0值。我会进行一些检查以确保该值是小写字母,例如toLowerCase()

const getBorder = ({ headingLevel } ) => {
  const headingLevelMap = {
    h1: 0.7,
    h2: 0.6,
    h3: 0.6,
  };

  return headingLevelMap[headingLevel] || 0;
}

const HeadingH2 = styled.headingLevel`
  color: ${colors.text};
  font-family: ${fonts.montSerrat};
  font-size: 1.6em;
  font-weight: ${fontWeights.light};
  letter-spacing: 0.2em;
  padding-bottom: 0.7em;
  border-bottom: ${getCorrectBorderBottom}em solid black
  position: relative;
  text-transform: uppercase;
  text-align: center;
  &:after{
    content: "";
    display: block;
    height: 3px;
    width: 45px;
    background-color: currentColor;
    /* position */
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  }
`;

我还要检查如果headingLevel中传递的值不是6个标题级别中的任何一个,则它应该具有您想要的默认值。

以上只是快速的伪代码,但希望能在这里得到一般的想法?如果没有,请通知我。

我还建议您将Title组件拆分为单独的组件。

答案 2 :(得分:0)

您应该明确地检查以下内容:typestyle

您可以编写动态CSS的最好方法(对我来说)。与react完美搭配,即使您需要也可以与ssr配合使用...

答案 3 :(得分:0)

可能的答案:

我将以下CSS规则添加到一个单独的文件中,如下所示。 我创建了一个返回字符串的函数。我可以导入此功能,并将这些规则添加到所需的任何组件中。

export const borderBottom = () => {
  return `
   position: relative;
   text-transform: uppercase;
   text-align: center;
   &:after{
    content: "";
    display: block;
    height: 3px;
    width: 45px;
    background-color: currentColor;
    /* position */
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
  } 
`
 }

并在希望的任何标题或组件上像这样使用它:

import styled from 'styled-components';
import colors from '../../../../colors';
import fonts from '../../../../fonts';
import fontWeights from  '../../../../fontWeights';
import {borderBottom} from '../../../../css';

const HeadingH5 = styled.h5`
  color: ${colors.black};
  font-family: ${fonts.montSerrat};
  font-size: 1em;
  font-weight: ${fontWeights.light};
  letter-spacing: 0.1em;
  padding-bottom: 0.45em;
  margin-bottom: 25px;
  ${borderBottom}
`  
;

export default HeadingH5;

这对我有用。欢迎其他任何建议。

答案 4 :(得分:0)

您还可以使用css中的styled-components助手来创建SharedStyles.js文件。

demo中,您可以看到它的运行情况。 仅以继承的组件样式使用它无法正常工作。如果我将其添加到StyledBase,则此后变量未正确添加(悬停样式覆盖会停止工作)。 这就是为什么我将${borderBottom}复制到每个样式化组件Heading1 / Heading2而不是将其添加到StyledBase的原因。

我认为为标题准备一个水平道具是一个好主意,但我会通过创建HeadingBase组件并将样式添加到StyledBase组件中来进行不同处理(另请参见演示中的代码) )。

HeadingBase代码如下:

const HeadingBase = ({ className, children, level = 1 }) =>
    React.createElement(`h${level}`, { className }, children);

这是一个根据传递的属性level渲染h1,h2,...标签的组件(默认为h1)。 h标签接收className作为道具(样式化组件需要),并包含传递给该组件的子代。

SharedStyles.js

import { css } from "styled-components";

export const borderBottom = css`
    &:after{
        content: "";
        display: block;
        height: 3px;
        width: 200px;
        background-color: ${props => props.color || "black"};
        /* position */
        position: absolute;
        bottom: 0;
        left: 50%;
        transform: translateX(-50%);
`;

然后,您可以使用import { borderBottom } from "./SharedStyles";导入它,并将其添加到样式组件中,如下所示:

const Heading1= styled.h1`
    ${borderBottom}
`;