模块 scss 符号 class 选择器不工作

Module scss ampersand class selector not working

我有一个简单的 scss 文件

.navItem {
  cursor: pointer;
    
  &.active {
    color: $primaryPurple;
  }
    
  &:hover {
    color: $primaryPurple;
  }
    
  span {
    margin-left: 10px;
  }
}

出于某种原因,:hover 有效但 .active 无效。正如您在下图中看到的,li 显然具有活动 class,但我没有看到字体颜色 css 已更改。

为您提供 jsx 代码会有所帮助,但我会猜测您使用 active 作为字符串文字,因此您的代码看起来像

import styles from './componentName.module.css';

// and then in the component

<li className={`nav-item ${styles.AdminSideBar_navItem} ${whateverCondition ? 'active' : ''}`}>
     ...children...
</li>

这里的问题是 active class 和 AdminSideBar_navItem 一样也有一个后缀。为了使其正常工作,您需要像访问 AdminSideBar_navItem 一样访问它。所以代码应该是

<li className={`nav-item ${styles.AdminSideBar_navItem} ${whateverCondition ? styles.active : ''}`}>
     ...children...
</li>

在html中你会看到

 <li class="nav-item AdminSideBar_navItem_abcd active_bcde">

我在 this codesandbox 中放了一个简单的示例,您可以尝试一下,看看它是如何工作的。

TL;DR:将名称作为 JavaScript 对象传递,而不是简单的字符串。

其实这个问题来自css-modules配置。显然,基于嵌入图片中的AdminSideBar_navItem__1aFBc。您在 Webpack 配置中的 css-modules 配置是:

// webpack config

module.exports = {
  ~~~
  module: {
    ~~~

    rules: [
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            {
              loader: 'css-loader',
              options: {
                modules: true,
                importLoaders: 1,
                localIdentName: '[name]_[local]_[hash:base64:5]', // <=== Attention to this line
                sourceMap: true,
              }
            },
            ~~~
          ],
       }),
    ],
  },
  ~~~
};

因此,当您使用 css-modules 时,这意味着您将拥有如此专业的优势,例如更压缩的 css 捆绑文件或完全散列的不可读的丑化捆绑包。为了这些好处,您应该使用 CSS class 名称,如 JavaScript 对象,请注意以下 ReactJS 代码以及使用 css-modules:

import React from 'react';
import cn from 'classnames'; // <=== install it to have easy coding
import styles from '[pathToScssFiles]/styles.scss';

const MyComponent = ({ isActive }) => (
  <li className={cn(styles.navItem, isActive && styles.active)} />
);

我希望,您理解我的意思,您将 styles.active 作为一个简单的字符串传递:"active"。所以 css-modules 无法将您的 class 名称作为对象获取并像它所获取的一样将其作为简单字符串传递,因此,"active" **BUT** in the CSS bundle file the css-modulesuse the' [name][local][hash:base64:5]'` 变形其名称的模式。

您的 :hover 应该可以工作,而且它可以工作,因为任何人都无法更改它,它是 pseudo-class。

当然,为.active写一个奇怪的属性:

.navItem {
  cursor: pointer;
    
  &.active {
    fill: yellow;
  }

现在在 Webpack 为您制作的 CSS 包中寻找 fill: yellow。你看是:

.AdminSideBar_navItem__1aFBc .AdminSideBar_active__9be2a {
  fill: yellow;
}

注: ~~~表示等