React15 - React CSS Modules BEM命名实践

在 React 项目中使用 CSS Modules 并结合 BEM 命名规范时,你遇到的“对象名称不支持 -”问题,是因为 JavaScript 对象属性名中不能直接包含连字符,但可以通过 方括号语法 来访问。以下是几种常见且推荐的实践方式:


1. 使用方括号语法访问带连字符的类名

这是最直接的方法,保持 BEM 类名的原始风格(如 block__element--modifier)。

/* Button.module.css */
.button {
  /* 基础样式 */
}
.button__icon {
  /* 元素样式 */
}
.button--primary {
  /* 修饰符样式 */
}
// Button.jsx
import styles from "./Button.module.css";

function Button({ primary, children }) {
  return (
    <button
      className={`
        ${styles.button}
        ${primary ? styles["button--primary"] : ""}
      `}
    >
      <span className={styles["button__icon"]}>✨</span>
      {children}
    </button>
  );
}

优点:完全保留 BEM 的可读性,符合团队规范。
缺点:每次访问都需要方括号,略显繁琐,组合多个类时可能需要借助工具。


2. 改用驼峰命名 + CSS Modules 转换

CSS Modules 默认支持驼峰命名,你可以将 BEM 风格转换为驼峰形式,然后直接用点号访问。这种方法更接近常规的对象属性访问。

/* Button.module.css */
.button {
  /* ... */
}
.buttonIcon {
  /* ... */
}
.buttonPrimary {
  /* ... */
}
// Button.jsx
import styles from "./Button.module.css";

function Button({ primary, children }) {
  return (
    <button
      className={`${styles.button} ${primary ? styles.buttonPrimary : ""}`}
    >
      <span className={styles.buttonIcon}>✨</span>
      {children}
    </button>
  );
}

优点:书写简洁,无需方括号,IDE 自动补全友好。
缺点:与 BEM 原始命名习惯略有差异,需要团队约定转换规则(例如 block__element 变为 blockElementblock--modifier 变为 blockModifier)。


3. 使用工具库简化类名组合

推荐使用 clsxclassnames 来动态组合类名,尤其适合条件判断较多的情况。

npm install clsx
import clsx from "clsx";
import styles from "./Button.module.css";

function Button({ primary, children }) {
  return (
    <button
      className={clsx(styles.button, primary && styles["button--primary"])}
    >
      <span className={styles["button__icon"]}>✨</span>
      {children}
    </button>
  );
}

clsx 还支持对象语法,更简洁:

className={clsx(styles.button, {
  [styles['button--primary']]: primary,
})}

4. 结合 CSS Modules 的 composes 复用样式

如果 BEM 修饰符需要继承基础样式,可以利用 CSS Modules 的 composes 特性,在 CSS 层面完成复用,减少 JS 中的逻辑。

/* Button.module.css */
.button {
  /* 基础样式 */
}
.button--primary {
  composes: button;
  /* 覆盖或新增样式 */
}

然后在 JS 中只需要一个类名:

<button className={primary ? styles["button--primary"] : styles.button}>
  {children}
</button>

总结

方式 适用场景
方括号语法 希望完全保留 BEM 原始命名,团队规范明确
驼峰命名 追求书写便捷、自动补全,可调整命名规范
工具库(clsx) 需要大量条件类名,代码更清晰、可维护
composes 修饰符依赖基础样式,希望减少 JS 条件判断

你可以根据团队习惯和项目复杂度选择一种或混合使用。无论哪种方式,CSS Modules 都能有效隔离样式,结合 BEM 则能保证样式命名清晰、可维护。

posted @ 2026-03-22 23:58  箫笛  阅读(1)  评论(0)    收藏  举报