01-React基础入门——08-样式处理方案
·

样式处理方案
一、样式处理方式概览
在 React 中,有多种处理样式的方法,每种都有其适用场景。
| 方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 行内样式 | 动态样式、简单组件 | 直观、动态 | 性能差、不支持伪类 |
| CSS 模块 | 中小型项目 | 作用域隔离、简单 | 需要配置 |
| CSS-in-JS | 大型项目、组件库 | 动态、类型安全 | 运行时开销 |
| Tailwind CSS | 快速开发 | 实用优先、体积小 | 学习曲线 |
| Less/Sass | 传统项目 | 功能丰富 | 全局作用域 |
二、行内样式 (Inline Styles)
2.1 基础用法
function Button() {
const buttonStyle = {
backgroundColor: '#007bff',
color: 'white',
padding: '10px 20px',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
};
return <button style={buttonStyle}>点击我</button>;
}
2.2 动态样式
function DynamicButton({ primary, disabled }) {
const styles = {
backgroundColor: primary ? '#007bff' : '#6c757d',
color: 'white',
padding: '10px 20px',
opacity: disabled ? 0.5 : 1,
cursor: disabled ? 'not-allowed' : 'pointer'
};
return <button style={styles} disabled={disabled}>按钮</button>;
}
2.3 条件样式合并
function StatusBadge({ status }) {
const baseStyles = {
padding: '4px 8px',
borderRadius: '4px',
fontSize: '12px'
};
const statusStyles = {
success: { backgroundColor: '#28a745', color: 'white' },
warning: { backgroundColor: '#ffc107', color: '#333' },
error: { backgroundColor: '#dc3545', color: 'white' }
};
return (
<span style={{ ...baseStyles, ...statusStyles[status] }}>
{status}
</span>
);
}
三、CSS 模块 (CSS Modules)
3.1 创建 CSS 模块文件
Button.module.css
.button {
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
}
.buttonPrimary {
background-color: #007bff;
}
.buttonSecondary {
background-color: #6c757d;
}
.disabled {
opacity: 0.5;
cursor: not-allowed;
}
3.2 使用 CSS 模块
import styles from './Button.module.css';
function Button({ variant = 'primary', disabled }) {
const buttonClass = `
${styles.button}
${variant === 'primary' ? styles.buttonPrimary : styles.buttonSecondary}
${disabled ? styles.disabled : ''}
`;
return <button className={buttonClass} disabled={disabled}>按钮</button>;
}
3.3 组合样式
import styles from './Card.module.css';
function Card({ title, children }) {
return (
<div className={styles.card}>
<div className={styles.header}>
<h3 className={styles.title}>{title}</h3>
</div>
<div className={styles.body}>{children}</div>
</div>
);
}
四、CSS-in-JS (Styled Components)
4.1 安装与配置
npm install styled-components
4.2 基础使用
import styled from 'styled-components';
const Button = styled.button`
background-color: #007bff;
color: white;
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: #0056b3;
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
`;
function App() {
return <Button>点击我</Button>;
}
4.3 动态样式
const Button = styled.button`
background-color: ${props => props.primary ? '#007bff' : '#6c757d'};
color: white;
padding: ${props => props.large ? '12px 24px' : '8px 16px'};
font-size: ${props => props.large ? '16px' : '14px'};
border: none;
border-radius: 4px;
cursor: pointer;
&:hover {
background-color: ${props => props.primary ? '#0056b3' : '#5a6268'};
}
`;
function App() {
return (
<div>
<Button primary>主要按钮</Button>
<Button>次要按钮</Button>
<Button large primary>大号按钮</Button>
</div>
);
}
4.4 样式继承
const BaseButton = styled.button`
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
`;
const PrimaryButton = styled(BaseButton)`
background-color: #007bff;
color: white;
&:hover {
background-color: #0056b3;
}
`;
const SecondaryButton = styled(BaseButton)`
background-color: #6c757d;
color: white;
`;
五、Tailwind CSS
5.1 安装配置
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
5.2 基础使用
function Button({ children, primary }) {
return (
<button
className={`
px-4 py-2 rounded font-semibold
${primary
? 'bg-blue-500 text-white hover:bg-blue-600'
: 'bg-gray-500 text-white hover:bg-gray-600'
}
`}
>
{children}
</button>
);
}
5.3 条件样式
function Card({ variant, children }) {
const variants = {
default: 'bg-white border-gray-200',
primary: 'bg-blue-50 border-blue-200',
warning: 'bg-yellow-50 border-yellow-200',
error: 'bg-red-50 border-red-200'
};
return (
<div className={`p-4 border rounded-lg shadow ${variants[variant]}`}>
{children}
</div>
);
}
5.4 使用 clsx 简化类名
npm install clsx
import clsx from 'clsx';
function Button({ primary, size = 'medium', disabled }) {
return (
<button
className={clsx(
'rounded font-semibold transition-colors',
{
'bg-blue-500 text-white hover:bg-blue-600': primary,
'bg-gray-500 text-white hover:bg-gray-600': !primary,
'px-2 py-1 text-sm': size === 'small',
'px-4 py-2 text-base': size === 'medium',
'px-6 py-3 text-lg': size === 'large',
'opacity-50 cursor-not-allowed': disabled
}
)}
disabled={disabled}
>
按钮
</button>
);
}
六、Less/Sass
6.1 安装
npm install sass
6.2 创建 SCSS 文件
styles/variables.scss
$primary-color: #007bff;
$secondary-color: #6c757d;
$border-radius: 4px;
Button.scss
@import './variables';
.button {
padding: 10px 20px;
border: none;
border-radius: $border-radius;
cursor: pointer;
&-primary {
background-color: $primary-color;
color: white;
&:hover {
background-color: darken($primary-color, 10%);
}
}
&-secondary {
background-color: $secondary-color;
color: white;
}
}
6.3 在 React 中使用
import './Button.scss';
function Button({ variant = 'primary', children }) {
return (
<button className={`button button-${variant}`}>
{children}
</button>
);
}
七、样式优先级与最佳实践
7.1 样式优先级顺序
- 行内样式 - 优先级最高(不推荐过度使用)
- CSS 模块 - 作用域隔离,优先级中等
- 全局 CSS - 优先级最低
7.2 最佳实践建议
// ✅ 使用 CSS 变量实现主题
const theme = {
colors: {
primary: '#007bff',
secondary: '#6c757d',
success: '#28a745',
danger: '#dc3545'
},
spacing: {
sm: '8px',
md: '16px',
lg: '24px'
}
};
// ✅ 提取公共样式
const commonStyles = {
flexCenter: {
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}
};
// ✅ 使用 CSS 变量
// global.css
:root {
--primary-color: #007bff;
--text-color: #333;
}
// 组件中使用
<div style={{ color: 'var(--text-color)' }}>内容</div>
八、性能优化建议
| 问题 | 解决方案 |
|---|---|
| CSS-in-JS 运行时开销 | 使用零运行时方案(Linaria、Vanilla Extract) |
| 样式重复计算 | 使用 styled-components 的 babel 插件 |
| 全局样式污染 | 使用 CSS 模块或 CSS-in-JS |
| 未使用的样式 | 使用 PurgeCSS(Tailwind 自带) |
九、练习题
基础题
- 创建一个卡片组件,支持不同主题(light/dark)
- 实现一个按钮组件,支持 primary、secondary、danger 三种变体
进阶题
- 实现一个响应式导航栏,移动端显示汉堡菜单
- 创建一个支持主题切换的组件(亮色/暗色模式)
参考答案
// 1. 主题切换组件
const ThemeContext = React.createContext();
function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light');
const toggleTheme = () => setTheme(theme === 'light' ? 'dark' : 'light');
const themeStyles = {
light: {
backgroundColor: '#fff',
color: '#333'
},
dark: {
backgroundColor: '#333',
color: '#fff'
}
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme, themeStyles: themeStyles[theme] }}>
{children}
</ThemeContext.Provider>
);
}
// 2. 响应式导航栏(CSS 模块 + 媒体查询)
// Navbar.module.css
.nav {
display: flex;
justify-content: space-between;
padding: 1rem;
}
.menu {
display: flex;
gap: 1rem;
}
.hamburger {
display: none;
}
@media (max-width: 768px) {
.menu {
display: none;
}
.menuOpen {
display: flex;
flex-direction: column;
position: absolute;
top: 60px;
left: 0;
right: 0;
background: white;
padding: 1rem;
}
.hamburger {
display: block;
}
}
十、小结
| 场景 | 推荐方案 |
|---|---|
| 快速原型 | Tailwind CSS |
| 组件库开发 | CSS-in-JS (styled-components) |
| 中小型项目 | CSS 模块 |
| 大型应用 | CSS-in-JS + CSS 变量 |
| 现有项目迁移 | Less/Sass |
核心要点:
- 根据项目规模选择合适的方案
- 保持样式的一致性
- 注意性能影响
- 优先使用作用域隔离
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)