第一次使用 styled-components

styled-components 是 React 中最流行、最强大的 CSS-in-JS 方案之一。

下面我会帮你系统梳理一套"快速上手 + 常用实战场景代码"清单,你照着练一遍就能快速掌握 90% 的日常用法。


🧩 一、核心概念理解

✅ 什么是 styled-components?

它让你能在 React 组件中写出这样的代码:

css 复制代码
import styled from "styled-components";

const Button = styled.button`
  background: #007bff;
  color: white;
  padding: 8px 16px;
  border-radius: 8px;
  border: none;

  &:hover {
    background: #0056b3;
  }
`;

export default function App() {
  return <Button>点击我</Button>;
}

👉 样式写在组件里(支持所有 CSS 语法),自动生成唯一 className,避免命名冲突。


🚀 二、快速入门步骤

1️⃣ 安装

复制代码
npm install styled-components

(TS 项目建议再装)

css 复制代码
npm install --save-dev @types/styled-components

2️⃣ 创建样式组件

javascript 复制代码
import styled from "styled-components";

const Container = styled.div`
  max-width: 1200px;
  margin: 0 auto;
`;

export default function App() {
  return <Container>Hello styled-components</Container>;
}

🧱 三、开发中常用实战场景

🧠 1. 动态样式(根据 props 改变样式)

css 复制代码
const Button = styled.button<{ $primary?: boolean }>`
  background: ${({ $primary }) => ($primary ? "#007bff" : "#ccc")};
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 6px;
`;

export default function App() {
  return (
    <>
      <Button $primary>主要按钮</Button>
      <Button>次要按钮</Button>
    </>
  );
}

✅ 关键:props 前加 $ 可避免 TS 报错并防止传到 DOM。


🎨 2. 主题(ThemeProvider)

全局定义主题(颜色、字号等):

javascript 复制代码
import styled, { ThemeProvider } from "styled-components";

const theme = {
  colors: {
    primary: "#007bff",
    secondary: "#6c757d",
  },
};

const Title = styled.h1`
  color: ${({ theme }) => theme.colors.primary};
`;

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <Title>这是标题</Title>
    </ThemeProvider>
  );
}

🧩 3. 样式继承(继承另一个 styled 组件)

ini 复制代码
const Button = styled.button`
  background: gray;
  color: white;
`;

const PrimaryButton = styled(Button)`
  background: blue;
`;

📦 4. 嵌套选择器 & 状态样式

css 复制代码
const Card = styled.div`
  padding: 16px;
  border: 1px solid #eee;

  h3 {
    margin-bottom: 8px;
  }

  &:hover {
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  }
`;

🧮 5. 响应式写法(内联媒体查询)

css 复制代码
const Box = styled.div`
  width: 100%;
  background: lightgray;

  @media (min-width: 768px) {
    background: pink;
  }
`;

🪄 6. 动画(使用 keyframes)

css 复制代码
import styled, { keyframes } from "styled-components";

const fadeIn = keyframes`
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
`;

const AnimatedDiv = styled.div`
  animation: ${fadeIn} 0.5s ease-in-out;
`;

🧩 7. 全局样式(GlobalStyle)

javascript 复制代码
import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
  body {
    margin: 0;
    font-family: 'Inter', sans-serif;
    background: #f8f9fa;
  }
`;

export default function App() {
  return (
    <>
      <GlobalStyle />
      <div>Hello World</div>
    </>
  );
}

⚙️ 8. 组件之间复用 mixin(常用技巧)

javascript 复制代码
import { css } from "styled-components";

const flexCenter = css`
  display: flex;
  justify-content: center;
  align-items: center;
`;

const Box = styled.div`
  ${flexCenter};
  height: 100px;
  background: #eee;
`;

🧱 9. 条件样式组合

ini 复制代码
const Tag = styled.span<{ $type: "success" | "error" }>`
  color: ${({ $type }) => ($type === "success" ? "green" : "red")};
  border: 1px solid currentColor;
  padding: 4px 8px;
  border-radius: 4px;
`;

🧩 10. 动态组件类型(as)

javascript 复制代码
const Button = styled.button`
  background: blue;
  color: white;
`;

export default function App() {
  return (
    <>
      <Button>按钮</Button>
      <Button as="a" href="#">
        链接样式
      </Button>
    </>
  );
}

🧠 四、进阶建议

场景 推荐方式
全局变量(颜色、间距) 使用 ThemeProvider
公共样式(布局、按钮) 定义 mixin 或基础组件
响应式布局 使用 CSS 媒体查询或 styled-system
动态切换主题 搭配 React Context + ThemeProvider
SSR(Next.js) 需配置 ServerStyleSheet

✅ 五、快速学习路线总结

阶段 目标 学习重点
入门 写静态组件 styled.div / 动态 props
实战 页面组件化 theme、嵌套、动画
进阶 复用与规范 mixin、全局样式、响应式
企业实践 主题系统 dark/light 模式、组件库封装

antd 组件开发

在 Ant Design 项目中优雅地修改组件样式(尤其是 Table、Form 等复杂组件) ------

是前端开发中最常见、也是最容易"写乱"的部分。


🧩 一、AntD + styled-components 修改样式的推荐策略

AntD 组件结构复杂(如 .ant-table, .ant-form-item 内部嵌套很多层),

直接 styled(组件) 往往不够精准。

👉 推荐的三种层级控制策略如下:

优先级 场景 推荐写法
1. 外层容器 + class 精准覆盖 修改组件内部结构样式 styled.div 包裹 .ant-xxx
2. styled(antd组件) 修改按钮、Input、Card 等简单组件 styled(Button)
⚙️ 3. 主题/Token 修改 全局颜色、边框、字体等统一 ConfigProvider theme={{ token: {} }}

🚀 二、实战写法(Table、Form)


🧱 1️⃣ 修改 Table 样式

AntD 的 Table 结构复杂(表头 + 单元格 + 滚动条),推荐使用外层容器 + class 选择器

css 复制代码
import styled from "styled-components";
import { Table } from "antd";

const StyledTableWrapper = styled.div`
  .ant-table {
    border-radius: 8px;
    overflow: hidden;
  }

  .ant-table-thead > tr > th {
    background: #fafafa;
    font-weight: 600;
  }

  .ant-table-tbody > tr:hover > td {
    background: #f0f7ff;
  }

  .ant-table-cell {
    padding: 12px 16px;
  }
`;

export default function Demo() {
  const dataSource = [{ key: 1, name: "张三", age: 28 }];
  const columns = [    { title: "姓名", dataIndex: "name" },    { title: "年龄", dataIndex: "age" },  ];

  return (
    <StyledTableWrapper>
      <Table dataSource={dataSource} columns={columns} pagination={false} />
    </StyledTableWrapper>
  );
}

✅ 这种写法最安全,不会影响全局,也能精确控制局部样式。


🧩 2️⃣ 修改 Form 样式

Form 内部同样嵌套 .ant-form-item.ant-form-item-label.ant-form-item-control

用容器 + 局部覆盖最稳定。

css 复制代码
import styled from "styled-components";
import { Form, Input, Button } from "antd";

const StyledForm = styled(Form)`
  max-width: 400px;
  margin: 0 auto;

  .ant-form-item {
    margin-bottom: 20px;
  }

  .ant-form-item-label > label {
    font-weight: 500;
  }

  .ant-input {
    border-radius: 6px;
    height: 40px;
  }

  .ant-btn-primary {
    border-radius: 6px;
    font-weight: 600;
  }
`;

export default function DemoForm() {
  return (
    <StyledForm layout="vertical">
      <Form.Item label="用户名">
        <Input placeholder="请输入用户名" />
      </Form.Item>
      <Form.Item label="密码">
        <Input.Password placeholder="请输入密码" />
      </Form.Item>
      <Form.Item>
        <Button type="primary" block>
          登录
        </Button>
      </Form.Item>
    </StyledForm>
  );
}

✅ 局部容器内重写 .ant-xxx,可实现完整控制而不影响全局。


🧠 三、推荐封装思路

✅ 1. 通用样式容器封装

定义一个全局通用容器组件,例如:

css 复制代码
// src/components/StyledWrapper.tsx
import styled from "styled-components";

export const StyledWrapper = styled.div`
  .ant-btn {
    border-radius: 6px;
  }

  .ant-input {
    border-radius: 4px;
  }

  .ant-table {
    border-radius: 8px;
  }
`;

使用时只需包裹局部区域:

xml 复制代码
<StyledWrapper>
  <Table ... />
</StyledWrapper>

✅ 适合团队统一风格管理,不污染 AntD 全局样式。


✅ 2. 封装通用组件

例如二次封装一个统一风格的表单:

javascript 复制代码
import { Form } from "antd";
import styled from "styled-components";

export const StyledForm = styled(Form)`
  .ant-form-item {
    margin-bottom: 16px;
  }
`;

之后你所有的表单都使用 <StyledForm>,统一视觉。


🎨 四、配合主题变量(ThemeProvider + ConfigProvider)

在大多数企业项目中,你可以用双层主题管理:

xml 复制代码
<ConfigProvider
  theme={{
    token: {
      colorPrimary: "#1677ff",
      borderRadius: 8,
    },
  }}
>
  <ThemeProvider theme={{ primary: "#1677ff" }}>
    <App />
  </ThemeProvider>
</ConfigProvider>

在 styled 里使用:

ini 复制代码
const Title = styled.h2`
  color: ${({ theme }) => theme.primary};
`;

在 AntD 中使用:

ini 复制代码
<Button type="primary">按钮</Button>

✅ 双主题体系:AntD 控制组件级 token,styled 控制自定义区域。


🧩 五、总结推荐写法清单

场景 推荐写法 说明
修改 AntD 简单组件(Button、Input) styled(Button) 简洁直接
修改复杂组件(Table、Form、Modal) styled.div + .ant-xxx 精确安全
全局视觉定制 ConfigProvider theme={{ token: {} }} 官方推荐
自定义样式变量 ThemeProvider 自定义区域样式
可复用的布局或容器 封装 StyledWrapper 团队统一样式管理

⚡ 六、额外技巧(进阶)

✅ 动态主题切换(亮色 / 暗色)

用 React Context + ThemeProvider 切换 theme,同时动态传给 ConfigProvider

✅ 控制样式作用域

如果需要防止样式"溢出",可以用:

ini 复制代码
const Wrapper = styled.div.attrs({ className: 'custom-scope' })``;

然后用 .custom-scope .ant-xxx 精准限定。

✅ 防止样式失效

AntD 样式层级高(有时用 inline style),

必要时可以使用 !important,但建议局部使用,不滥用。


相关推荐
Bigger3 小时前
🚀 真正实用的前端算法技巧:从 semver-compare 到智能版本排序
前端·javascript·算法
云枫晖3 小时前
Webpack系列-Output出口
前端·webpack
用户268001379193 小时前
有哪些高效的Python库可以用于解析淘宝评论的JSON数据?
前端·api
brzhang3 小时前
A Definition of AGI:用人的智力模型去量 AI,这事靠谱吗?
前端·后端·架构
一 乐3 小时前
宠物管理|宠物店管理|基于SSM+vue的宠物店管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·宠物
咖啡の猫3 小时前
Vue插件
前端·javascript·vue.js
韩劳模3 小时前
Canvas、SVG实现不规则区域高亮的方案说明
前端
张可爱4 小时前
20251026-从网页 Console 到 Python 爬虫:一次 B 站字幕自动抓取的实践与复盘
前端·python
咖啡の猫4 小时前
Vue中的自定义事件
前端·javascript·vue.js