1. 程式人生 > >React中使用css-module學習總結文件

React中使用css-module學習總結文件

css modules

1. 為什麼要使用css modules

不論是基於pure js或jquery等傳統的前端開發,還是基於react,vue等新框架的開發,都會遇到css汙染的問題。如果專案管理不標準,對於部分頁面定義的css樣式可能會影響到其他頁面的顯示效果,並且這類css汙染問題要排查及修改都比較麻煩。

為了解決這類問題,在之前的專案中,我們逐步找到了幾個好方法:

1. 在每個頁面的根節點中,設定root class,將所有的樣式定義在root class下

2. 使用BEM標準規範css樣式等

但是通過這類方法,也只能是通過人工的方式避免css汙染,漏網之魚還是有的。

所以在最近的react專案中,我們採用了css-module組建進行開發。

2. CSS Modules怎麼解決css汙染問題

在專案構建過程中,css-module會幫助重新構建class,對於其命名做hash運算,使它變得獨一無二作用於各個元件。比如我定義了一個.title的class,在編譯後會像這樣.title___30uvB。由於不同element的class命名不同,就不會出現互相干擾的情況。

3. React專案配置CSS Modules(webpack)

...
{
    test: /\.css$/,
    use: [
        {
            loader: 'style-loader'
        },
        {
            loader
: 'css-loader?modules&localIdentName=[name]-[hash:base64:5]' } ] }, ...

4. 在專案當中使用

Test.jsx

import React, { Component } from 'react';
// 將樣式檔案當成模組引入
import styles from "./test.css";


export default class Test extends Component {
    render() {
        return (
            <div>
                <div className={styles.test}>測試</div>
            </div>
        )
    }
}

test.css

.test {
    color: red;
}

以上就是CSS Modules的基本用法

5. 用法進階

全域性樣式和區域性樣式

開啟CSS Modules之後預設的樣式都為區域性樣式

// css 樣式
(:global)(.test1) {
    color: blue;
}
或者如下(定義多個全域性樣式)
:global {
    .test1 {
        color: blue;
    }
    .test2 {
        color: red;
    }
}

// 全域性樣式寫法和之前一樣
import React, { Component } from 'react';
import styles from "./test.css";
export default class Test extends Component {
    render() {
        return (
            <div>
                <div className="test1">測試</div>
            </div>
        )
    }
}

Compose 組合樣式

// 樣式檔案
.base { 
    font-size: 20px;
 }

.normal {
  composes: base;
  color: #333;
}

.disabled {
  composes: base;
  color: #ddd;
}
// 元件中
import React, { Component } from 'react';
import styles from "./test.css";
export default class Test extends Component {
    render() {
        return (
            <div>
                <div className="normal">測試</div>
            </div>
        )
    }
}
// 編譯後的html檔案
<d class="div--base-daf62 div--normal-abc53">測試</div>
// 由於在 .normal 中 composes 了 .base,編譯後會 normal 會變成兩個 class。

6. CSS Modules React 專案實踐

import classNames from 'classnames';
import styles from './dialog.css';

export default class Dialog extends React.Component {
  render() {
    const cx = classNames({
      [styles.confirm]: !this.state.disabled,
      [styles.disabledConfirm]: this.state.disabled
    });

    return <div className={styles.root}>
      <a className={cx}>Confirm</a>
      ...
    </div>
  }
}

7. 關於樣式覆蓋問題

使用css-modules有個很頭疼的問題,就是如果react中使用了其他元件,在外部是辦法通過class覆蓋的方式修改原有樣式。

因為CSS Modules 不會覆蓋屬性選擇器,所以可以利用屬性選擇器來解決這個問題

// 元件中
...
return (
    <div data-role='test'>
        測試
    </div>
)
...
// 樣式
[data-role="test"] {
    color: red;
}