Skip to content

第七章 样式处理——样式私有化

内容前瞻

本章将探讨 样式私有化 的多种方法,包括基于 JSX 的内联样式、CSS Module、CSS-in-JS 等技术

  • 样式私有化的核心目标:避免样式冲突,提高组件独立性
  • 不同方法的优缺点及适用场景
  • 动态样式管理与样式复用的实现方式

样式私有化方法

1. 基于 JSX 的内联样式

  • 实现方式:每个样式基于 JSX 的 style 属性,使用 JavaScript 对象存储样式
  • 优点
    • 动态设置样式灵活,优先级高
  • 缺点
    • 不利于样式复用
    • 不支持伪类、伪元素等 CSS 特性

示例

jsx
const styles = {
  container: {
    padding: '10px',
    backgroundColor: '#f0f0f0',
  },
  title: {
    fontSize: '20px',
    color: '#333',
  },
};

function Component() {
  return (
    <div style={styles.container}>
      <h1 style={styles.title}>Hello, World!</h1>
    </div>
  );
}

2. 基于 CSS Module

  • 实现方式:通过打包工具(如 Webpack)将类名编译为唯一值,避免样式冲突
  • 文件命名xxx.module.css
  • 特点
    • 基于键值对(kv 对)导出类名
    • 使用时通过 import 引入文件,通过模板字符串获取类名

示例

css
/* styles.module.css */
.container {
  padding: 10px;
  background-color: #f0f0f0;
}

.title {
  font-size: 20px;
  color: #333;
}
jsx
import styles from './styles.module.css';

function Component() {
  return (
    <div className={styles.container}>
      <h1 className={styles.title}>Hello, World!</h1>
    </div>
  );
}
  • 全局样式:使用 :global(.style-name) 让类名不受编译影响
  • 样式继承:通过 composes: class-style-name 继承其他样式

3. 基于 CSS-in-JS

  • 实现方式:动态管理 CSS,样式与组件逻辑紧密结合
  • 常用库
    • react-jss:通过 createUseStyles 创建样式
    • styled-components:通过 styled.nav`` 创建样式组件

示例(react-jss)

jsx
import { createUseStyles } from 'react-jss';

const useStyles = createUseStyles({
  container: {
    padding: '10px',
    backgroundColor: '#f0f0f0',
  },
  title: {
    fontSize: '20px',
    color: '#333',
  },
});

function Component() {
  const classes = useStyles();
  return (
    <div className={classes.container}>
      <h1 className={classes.title}>Hello, World!</h1>
    </div>
  );
}

示例(styled-components)

jsx
import styled from 'styled-components';

const Container = styled.div`
  padding: 10px;
  background-color: #f0f0f0;
`;

const Title = styled.h1`
  font-size: 20px;
  color: #333;
`;

function Component() {
  return (
    <Container>
      <Title>Hello, World!</Title>
    </Container>
  );
}
  • 动态样式:可以传递参数,样式对象的 value 可以作为函数接收 props

示例

jsx
const useStyles = createUseStyles({
  button: (props) => ({
    backgroundColor: props.primary ? 'blue' : 'gray',
    color: 'white',
    padding: '10px 20px',
  }),
});

function Button({ primary }) {
  const classes = useStyles({ primary });
  return <button className={classes.button}>Click Me</button>;
}

重难点 & 容易忽视的点

1. CSS Module 的全局样式

  • 使用 :global(.style-name) 可以让类名不受编译影响,适用于需要全局生效的样式

2. CSS-in-JS 的性能问题

  • 动态生成样式可能会影响性能,尤其是在大型项目中
  • 可以通过提取静态样式、使用缓存等方式优化

3. 样式复用与继承

  • CSS Module:通过 composes 实现样式继承
  • CSS-in-JS:通过函数参数或样式组合实现动态样式复用

总结

  • JSX 内联样式:灵活但不利于复用,不支持伪类
  • CSS Module:通过唯一类名避免冲突,支持全局样式和样式继承
  • CSS-in-JS:动态管理样式,适合复杂场景,但需注意性能问题