React中使用css-module學習總結文件
阿新 • • 發佈:2019-01-26
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;
}