简单介绍CSS Modules、React-CSS-Modules、classnames概念及用法
CSS Modules
A CSS Module is a CSS file in which all class names and animation names are scoped locally by default.
CSS Modules实现了css模块化,我们可以像引入js文件一样来引入css文件,所有样式都是局部化的,不用担心命名冲突,全局污染的问题,此外,还能通过CSS Modules提供的组合方法达到对样式的复用。CSS Modules多应用于提取公共组件或业务公共组件场景中
CSS Modules的配置
webpack css-loader已经内置CSS Modules功能,启用css Modules代码如下:1
2
3
4
5
6
7
8
9module: {
loaders: [
// ...
{
test: /\.css$/,
loader: "style-loader!css-loader?modules&localIdentName=[path][name]---[local]---[hash:base64:5]"
},
]
}
其中,关键词modules
,表示启用CSS Modules 功能,localIdentName
用于定制生成样式的命名规则
CSS Modules的使用
在React环境中,CSS Modules 看起来是这样子的:1
2
3
4
5
6
7
8
9
10
11
12import React, { Component } from 'react';
import styles from './table.css';
export default class Table extends Component {
render () {
return <div className={styles.table}>
<div className={styles.row}>
<div className={styles.cell}>A0</div>
<div styleName='cell'>B0</div>
</div>
</div>;
}
}
组件渲染出来后会生成类似于这样的一个标记:
1 | <div class="table__table___32osj"> |
同时也会生成一个以hash映射形式来匹配相应的类名的table.css.js文件:
1 | module.exports = { |
此外,CSS Modules还提供了compose组合方法来处理样式复用,示例代码如下:
1 | .className { |
CSS Modules优点
- 所有样式都是局部化的,解决了命名冲突和全局污染问题
- class名的生成规则配置灵活
- 引入组件,只需引用组件的js文件,不需要额外去引入css文件
- 依然是css,学习成本几乎为零
目前存在的问题
- 必须使用驼峰式的命名(若以‘-’命名,则需要通过styles[]这种形式关联)
- 需要频繁的输入style.**
- 引用一个未定义的 CSS 模块时解析结果为 undefined ,但并无相关警告提示
React CSS Modules
React CSS Modules implement automatic mapping of CSS modules. Every CSS class is assigned a local-scoped identifier with a global unique name. CSS Modules enable a modular and reusable CSS!
React CSS Modules实现了自动化映射 CSS modules,完美得解决了上述问题,它的原理是扩展了render方法,根据styleName的值去在关联的styles对象中查找相应的css-module,并给每个 CSS 类赋予一个带有全局唯一名字的本地标识符的类名。
React CSS Modules的使用
使用React css Modules上述例子可以简化为:
1 | import React from 'react'; |
Options配置
React CSS Modules提供了options作为第三个参数来对CSS Modules的配置
- allowMultiple 默认为false
- errorWhenNotFound 默认为true
1
CSSModules(Component, styles, options); // options = { allowMultiple: false, errorWhenNotFound: true }
React CSS Module的优点
- 我们不用再关注是否使用驼峰来命名class名
- 不用每次使用CSS Modules都用styles.**来关联对象
- 通过
<div className="global-css" styleName="local-css"></div>
明显区分全局CSS和CSS Modules - 当styleName关联了一个undefined CSS Modules时,会得到一个警告信息(errorWhenNotFound option)
- 强制使用一个CSS Modules, 推崇使用CSS Modules 的样式组合(allowMultiple option)
classnames
A simple javascript utility for conditionally joining classNames together.
在业务开发中,少不了对类的操作,以button组件为例,如果不使用classnames库,需要这样处理动态类名
1 | import React,{ Component } from 'react'; |
使用了classnames库,代码简化如下:
1 | import React,{ Component } from 'react'; |
至此,有了CSS Modules, React-CSS-Modules,classnames,通过简单配置,我们就可以把精力集中在编写css样式上了,而无须为类名的命名感到头疼,也不用频繁地使用styles.**来关联样式,当styleName关联了一个undefiend CSS Modules时,会得到一个警告信息,而不用去查找原因去看DOM结点,再加之有了classnames的动态操作样式的助攻,我们的代码将会变得更加简明和清晰!
参考文档:
- https://github.com/css-modules/css-modules
- https://github.com/gajus/react-css-modules
- https://github.com/JedWatson/classnames