React中styled-components的使用

1. 环境安装

  # 安装包 
  yarn add styled-components
  # 如果有ts则还需安装 
  yarn add "@types/styled-components"

2. 引入

import styled from "styled-components";

3. 逐步掌握

1. 普通用法

样式部分

.contact__intro {
  font: size 16px;
  margin-bottom: 0;
}

.contact__intro strong {
  font-weight: 600;
}

标签部分

<p className="contact__intro">
  {name} is a <strong>{age} years</strong> old{" "}
  <strong>{introduction}</strong>
</p>

使用后

{/* 样式部分 */}
const ContactIntro = styled.p`
  font: size 16px;
  margin-bottom: 0;
  strong {
    font-weight: 600;
  }
`;
{/* 标签部分 */}
<ContactIntro>
  {name} is a <strong>{age} years</strong> old{" "}
  <strong>{introduction}</strong>
</ContactIntro>

2. 变量导入

{/* 标签部分 */}
<Contact gender={gender}>
...
</Contact >
{/* 样式部分 */}
const Contact = styled.div<{ gender: string }>`
  border: 1px solid #dedede;
  border-radius: 5px;
  padding: 15px;
  margin: 15px;
  background-color: ${(props) =>
    props.gender === "female" ? "tomato" : "green"};
  color: white;
`;

3. 用attrs封装组件属性,提高代码复用

创建一个简单的密码控件

// 用attrs封装组件属性,提高代码复用
import styled from "styled-components";

const PasswordInput = styled.input.attrs({
  type: "password",
  padding: (props: { "data-em"?: string }) => props["data-em"] || "0.5em",
  margin: (props: { "data-em"?: string }) => props["data-em"] || "0.5em",
})`
  border: 2px solid #dedede;
  border-radius: 5px;
  color: #4a4a4a;
  margin: ${(props) => props.margin};
  padding: ${(props) => props.padding};
`;

export default PasswordInput;

使用该组件

  <PasswordInput name="pass1" />
  <PasswordInput name="pass2" data-em="2em" />

4. 实现样式继承

const Contact = styled.div`
  border: 1px solid #dedede;
  border-radius: 5px;
  padding: 15px;
  margin: 15px;
  color: white;
`;

// 注意 Contact.extend的方法已经被废弃 以下方法相当于继承
// 第二个注意的是styled的值都不用引号引起来
const ContactFemale = styled(Contact)`
  background-color: tomato;
`;

const ContactMale = styled(Contact)`
  background-color: green;
`;

// 使用
const RenderContact = ({ name, gender, age, introduction }: Props) => {
  const ContactComponent = gender === "female" ? ContactFemale : ContactMale;
  return (
    <ContactComponent>
      <ContactName>{name}</ContactName>
      <ContactIntro>
        {name} is a <strong>{age} years</strong> old{" "}
        <strong>{introduction}</strong>
      </ContactIntro>
    </ContactComponent>
  );
};

5. 设置全局样式

injectGlobal已经被废弃,先在用 createGlobalStyle 替代

import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
body {
  padding: 0;
  margin: 0;
  color: ${(props) => (props.whiteColor ? "blue" : "black")};
  font-family: ${(props) => props.theme.fontFamily};
  line-height:2em;
}
`;

ReactDOM.render(
  <React.StrictMode>
    <App />
    <GlobalStyle whiteColor theme={{ fontFamily: "Helvetica Neue" }} />
  </React.StrictMode>,
  document.getElementById("root")
);

6. 主题设置

import { createGlobalStyle, ThemeProvider } from "styled-components";

const theme = {
  primary: "pink",
  fontFamily: "Helvetica Neue",
};
ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider theme={theme}>
      <App />
      <GlobalStyle whiteColor />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById("root")
);

下层组件直接在props中可以获取到theme,如下方式:

const GlobalStyle = createGlobalStyle`
body {
  padding: 0;
  margin: 0;
  color: ${(props) => (props.whiteColor ? "blue" : "black")};
  font-family: ${(props) => props.theme.fontFamily};
  line-height:2em;
}
`;

7. 动画实现

// 用attrs封装组件属性,提高代码复用
import styled, { keyframes } from "styled-components";

const spin = keyframes`
from {
  transform:rotate(0deg);
  transform:rotate(359deg);
}`;
const PasswordInput = styled.input.attrs({
  type: "password",
  padding: (props: { "data-em"?: string }) => props["data-em"] || "0.5em",
  margin: (props: { "data-em"?: string }) => props["data-em"] || "0.5em",
})`
  border: ${(props) => `2px solid ${props.theme.primary}`};
  border-radius: 20px;
  color: #4a4a4a;
  margin: ${(props) => props.margin};
  padding: ${(props) => props.padding};
  animation: ${spin} 1s linear infinite;
`;

export default PasswordInput;

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容