我正在使用一个 React 组件库(React Toolbox),它使用 CSS 模块和 Webpack 在其 Tab 组件中输出此类:label___1nGy active___1Jur tab___Le7N
这tab
是我传递的 className 道具。和label
类active
来自图书馆。我想在 上应用一组不同的样式active
,例如.tab.active
wheretab
指的是我创建的样式并active
匹配库创建的生成选择器,但无法弄清楚如何使用 css-modules 执行此操作。我需要覆盖这个动态选择器:.label___1nGy.active___1Jur
。
5 回答
旧帖子但仍然相关,因此添加答案以帮助有类似问题的人
尽管仅在 CSS 模块中不可能实现,但 react-toolbox 库的作者实际上已经很好地解决了这个特殊问题
在https://github.com/react-toolbox/react-toolbox#customizing-components阅读他们更深入的 github 文档
特定组件的主题类列表也在他们网站上的组件演示页面上给出
在您的情况下,除了为选项卡传递 className 之外,您还将创建一个主题,其中包含覆盖默认主题的所需部分并将其作为theme
道具传递的类。例如一些类似的东西......
MyComponentWithTabs.css
.tab {
color: white;
}
MyTabTheme.css
.active {
color: hotpink;
}
MyComponentWithTabs.js
import styles from './MyComponentWithTabs.css'
import tabTheme from './MyTabTheme.css'
// blah blah...
return <Tab key={index} className={styles.tab} theme={tabTheme} />
在表面下,这使用了一个他们已经抽象到单独的库react-css-themr的装饰器,我建议也阅读一下,因为它解释了默认值如何与您的覆盖更深入地组合,包括他们使用的不同合并策略
CSS 模块不允许您安全地覆盖活动的类名(主要是设计使然)。实际上,它应该通过 API 公开,例如“activeClassName”。
如果维护人员不同意或者您需要快速执行此操作,那么您可以很容易地添加自己的活动类名,因为您的实现组件正在管理索引状态:
import {Tab, Tabs} from 'react-toolbox';
import styles from './MyTabs.css';
class MyTabs extends React.Component {
state = {
index: 1
};
handleTabChange(index) {
this.setState({ index });
}
render() {
const { index } = this.state;
return (
<Tabs index={index} onChange={this.handleTabChange}>
<Tab label="Tab0" className={index === 0 ? styles.active : null}>
Tab 0 content
</Tab>
<Tab label="Tab1" className={index === 1 ? styles.active : null}>
Tab 1 content
</Tab>
</Tabs>
);
}
}
免责声明:代码未经测试。
我有一个类似的案例,我像这样解决了它:
import classNames from 'classnames';
...
const activeClassName = {};
activeClassName[`${styles.active}`] = this.props.isActive;
const elementClassNames = classNames(styles.element, activeClassName);
return <div className={elementClassNames} />
我正在使用该classnames
包根据isActive
道具动态添加活动类。isActive
您可以提供任何布尔值来代替道具。
一种更简洁的方法可能是:
const elementClassNames = classNames(styles.element, {[styles.active]: this.props.isActive});
组样式加载器
您可以使用group-style-lader来覆盖组件的样式。此加载器为您提供了一种简单直观的方式来覆盖组件的样式。
配置加载器
安装装载机
npm install --save-dev group-style-loader
在你的 webpack 设置中配置加载器
module.exports = { module: { rules: [ { test: /\.css$/i, use: [ 'group-style-loader', 'style-loader', { loader: "css-loader", options: { modules: true } } ] } ] } };
你只需要把它放在
style-loader
或mini-css-extract-plugin
loader 之前。
覆盖组件的样式
下一个示例展示了如何从 App 组件中覆盖 Card 组件的样式。
您可以按照习惯定义组件的样式。
卡片.css
.container {
width: 300px;
height: 400px;
border-radius: 8px;
}
.title {
font-weight: bold;
font-size: 24px;
}
.summary {
margin-top: 24px;
font-size: 20px;
}
唯一不同的是,在Card 组件中,您将使用该mergeStyle
功能将自定义样式与组件的默认样式合并。
卡片.jsx
import React from 'react';
import { mergeStyle } from './card.css';
export function Card({ customStyle }) {
const style = mergeStyle(customStyle);
return (
<div className={style.container}>
<div className={style.title}>Title</div>
<div className={style.summary}>
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor.
</div>
</div>
)
}
然后,在App 组件中,要覆盖Card 组件的样式,您需要使用 separator 定义 Card 组件的自定义样式_
。所有使用此分隔符的类都将被分组到样式对象的card属性中。
应用程序.jsx
.title {
font-size: 32px;
font-weight: bold;
margin: 44px;
}
.list {
display: flex;
}
.card_title {
color: blue;
}
.card_summary {
color: green;
}
最后,您只需要通过它的属性传递Card 组件的自定义样式即可。customStyle
应用程序.jsx
import React from 'react';
import { Card } from './card';
import { style } from './app.css';
export function App() {
return (
<div>
<h1 className={style.title}>Group style</h1>
<div className={style.list}>
<Card/>
<Card customStyle={style.card}/>
</div>
</div>
);
}
在前面的例子中,你有两个Cards 组件,第一个使用它的默认样式,第二个使用我们定义的自定义样式。
group-style-loader
您可以在其存储库中看到有关如何使用的完整说明。
fileName.css 中的技巧
声明 className 后添加 className-active
.className{
background: white;
}
.className-active{
background: black;
}
<div className={'className className-active'} />
<div className={'className-active className'} />
div 总是黑色的