如何在 css 模块中嵌套 类 并做出反应?

How to nest classes in css modules and react?

我正在尝试在我的 React 项目中使用 CSS 模块。问题的第一部分是,如果我写嵌套的 css classes(使用 sass),我不知道我是否可以访问内部的,因为那些似乎是编译过的也变成独特的 class 名字。一些代码:

<div className={this.state.visible ? styles.header+" menu-visible" : styles.header}>
    <div className="menu">
        <a className="link">title</a>
    </div>
</div>

   .header {
       &.menu-visible {
            .menu {
                 display:block;
            }
        }
    }

我有一个包装 class,有时 "menu-visible" 会更改所有子项的属性,在 React 中这样做是不好的做法吗?

如果菜单可见,.header 中有多个 classes 会被更改,因此只更改包装会很方便 class,我可以在一些中引用子项吗方法?以便保留嵌套在 scss?

编辑

我能想到的一个解决方案是将 className="menu" 替换为 className={styles.header.menu} 但这似乎不起作用。问题是,如果 .menu 的父项具有 class 菜单可见,我希望 .menu 更改其属性。

还有另一种方法。我使用 classnames 包来执行此操作。

https://github.com/JedWatson/classnames

它看起来像这样

<div className={classnames('styles.header',{ 'menu-visible': this.state.visible})}>

我解决了。我认为我只是在脑海中做过头了。我可以写 styles.menu 而不是 styles.header.menu,即使它是嵌套的。

示例(React + JSX):

<div className={styles.header}>
  <div className={styles.menu}>
      Whatever
  </div>
</div>

.header {
   .menu {
      display: block;
   }
 }

您可以使用[class~=class名称]

.header {
   [class~=menu] {
      display: block;
   }
 }

不会被检测为 class 并保持不变。

更好地保留嵌套 类 和样式的替代解决方案是在使用像 sass 这样的预处理器时对所有嵌套 类 使用全局范围 :global或更少。

.header {
  :global {
    .menu {
      display: none;

      &.menu-visible {
        display:block;
      }
    }
  }
}
<div className={styles.header}>
  <div className="menu menu-visible">
      Whatever
  </div>
</div>

请注意,当深度嵌套选择器时,已接受答案中的解决方案可能会导致 css 包大小显着增加。

接受了多一层嵌套的解决方案

JSX:

<div className={styles.header}>
  <ul className={styles.menu}>
    <li className={styles.item}>
      Whatever
    </li>
  </ul>
</div>

SCSS:

.header {
   .menu {
      .item {
        display: block;
      }
   }
 }

输出(假设 css 模块的默认设置):

.myComponent_header__27ep6 .myComponent_menu__32Qvy  .myComponent_item__2RWLN {
  display: block
}

备选方案

更好的编写方法是松散地借用 BEM 方法并使用父选择器:

JSX:

<div className={styles.header}>
  <ul className={styles.headerMenu}>
    <li className={styles.headerMenuItem}>
      Whatever
    </li>
  </ul>
</div>

SCSS:

.header {
   &Menu {
     &Item {
       display: block;
     }
   }
 }

输出:

.myComponent_headerMenuItem__37djq { display: block }

不知道有没有帮助,我找到了如下方法:

文件:package.json

"dependencies": {
  ...,
  "sass": "^1.49.9"
}

文件:test.scss

.box {
    width: 100%;
}

.boxItem {
    background: red;

    &.first {
        background: blue;
    }

    &.second {
        background: silver;
    }
}

文件test.js

import React from 'react'
import styles from "./test.scss";

const test = () => {
  return (
    <div className={`${styles.box}`}>
      <div className={`${styles.boxItem} ${styles.first}`}>Test 01</div>
      <div className={`${styles.boxItem} ${styles.second}`}>Test 02</div>
      <div className={`${styles.boxItem}`}>Test 03</div>
    </div>
  );
};

导出默认测试;