CSS module和React 中的应用

为什么需要CSS模块化 ?

由于CSS的规则是全局性的,添加任何一个样式,在全局都有效,优点是方便复用,缺点是会根据权重的计算造成样式冲突,非常难以管理。

CSS 模块化的方案

有了钉子,自然就会有锤子。随着前端的发展出现了各种CSS模块解决方案,主要分两种:
一类是采用JS或者JSON 的方式写CSS,比如 jsxstyle,react-style,虽然可以采用JS成熟方案来管理css, 但是它无法使用postcss ,sass等css预处理器,并且衍生了大批的api, 使用的代价较大。
另一类还是采用css 来写样式, 不过是通过工具生成CSS作用域的方式实现模块化,比如CSS module。常用的BEM命名技巧或者团队中约定的方案来实现命名空间从而实现模块化,不过约定总会出现问题,于是就出现了通过工具,比如webpack的css-loader根据算法,实现css 模块化。

启用CSS

webpack 内置的 css-loader 自带了CSS modoule, 配置如下:

rules: [
      ...
      {
        test: /\.css$/,
        use: [
          'style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: true,
              localIdentName: '[name]__[local]--[hash:base64:5]' // 生成样式的命名规则
            }
           //或者采用loader: 'css?modules&localIdentName=[name]__[local]-[hash:base64:5]'的写法
          }
        ]
       }
    ]

create-react-app 2.0以上的版本中内置启动了CSS module, 如果需要特殊配置,则需要eject操作, 在webpack.config.js 中:

 // Adds support for CSS Modules (https://github.com/css-modules/css-modules)
// using the extension .module.css
      {
          test: cssModuleRegex,
          use: getStyleLoaders({
          importLoaders: 1,
          sourceMap: isEnvProduction && shouldUseSourceMap,
          modules: true,
          getLocalIdent: getCSSModuleLocalIdent,
          }),
      },
      

CSS module 用法

基本用法
/* components/Button.css */
.normal { /* normal 相关的所有样式 */ }
.disabled { /* disabled 相关的所有样式 */ }

// components/Button.js
import styles from './Button.css';
buttonElem.outerHTML = ``

//生成的HTML

CSS module 默认采用局部样式,即给每个css 名添加上了“:local”, 对应的全局性的写法:

/* 定义全局样式 */
:global(.btn) {
  color: red;
}

/* 定义多个全局样式 */
:global {
  .link {
    color: green;
  }
  .box {
    color: yellow;
  }
}

compose 组合样式:
对于样式复用,CSS module提供了唯一的方式 "compose":

/* components/Button.css */
.base { /* 所有通用的样式 */ }

.normal {
  composes: base;
  /* normal 其它样式 */
}

.disabled {
  composes: base;
  /* disabled 其它样式 */
}

import styles from './Button.css';
buttonElem.outerHTML = ``

// 生成后的html

多CSS class 的写法:

.normal {
  composes: base;
  /* normal 其它样式 */
}

.disabled {
  composes: base;
  /* disabled 其它样式 */
}

import styles from './Button.css';
buttonElem.outerHTML = ``

Sass 变量与JS共享

/* config.scss */
$primary-color: #f40;

// 内置语法,可以到处该变量
:export {
  primaryColor: $primary-color;
}

/* app.js */
import style from 'config.scss';

// 会输出 #F40
console.log(style.primaryColor);
使用技巧

Css module 作者建议:
1.不使用选择器,只使用 class 名来定义样式
2.不层叠多个 class,只使用一个 class 把所有样式定义好
3.不嵌套
4.使用 composes 组合来实现复用

Css module 在React中的实践

采用classnames来增强CSS module 在react 中的使用,类似Angular 中的样式指令:

var classNames = require('classnames');

class Button extends React.Component {
  // ...
  render () {
    var btnClass = classNames({
      btn: true,
      'btn-pressed': this.state.isPressed,
      'btn-over': !this.state.isPressed && this.state.isHovered
    });
    return ;
  }
}
应用全局样式
...
// 引入全局样式 
import 'xxx/common.css';
// 引入局部样式
import styles from './xxx.module.css';
...
...

参考链接:https://zhuanlan.zhihu.com/p/20495964

你可能感兴趣的:(CSS module和React 中的应用)