每日優質NPM包之classnames
一、classnames
現在到處都追求效率開發,所謂存在即合理,各種各樣的開源包/專案火熱,也是因為他們大大解決了之前複雜的邏輯.作為榜上前10的熱門包:classnames.還真需要了解了解它才能仗'包'走天涯
官方定義: A simple JavaScript utility for conditionally joining classNames together.
理解: 幫助你在React專案更好地使用className
二、使用方法
在認識classnames之前,你可能會有一個疑問: 我發誓我現在react自帶的className
用得挺好的,還需要引入classnames嗎?
先舉個小反例吧
錯誤
import styles from './style.less'
<div className={styles.div styles.div1}></div> //不允許存在多個變數
正確
import styles from './style.css' import classNames from 'classnames' let divClass = classNames({ 'div': true, 'div1': true }) <div className={divClass}></div> //輸出class="div div1"
當然,機智的你當然想到了可以用字串模板解決
<div className={`${styles.div} ${styles.div1}`}></div>
"幹嘛弄這麼麻煩?直接import './style.css'
不就行了?"
import from './styles.css'
<div className="div div1></div>
大兄弟所言甚是.上面只是我在專案中使用antd-pro
CSS Modules編碼方式
簡單介紹一下什麼是CSS Modules
:
由於專案開發逐漸龐大過程中,對於樣式有兩個不得不考慮的問題(這也是CSS Modules
全域性汙染 —— CSS 檔案中的選擇器是全域性生效的,不同檔案中的同名選擇器,根據 build 後生成檔案中的先後順序,後面的樣式會將前面的覆蓋;
選擇器複雜 —— 為了避免上面的問題,我們在編寫樣式的時候不得不小心翼翼,類名裡會帶上限制範圍的標識,變得越來越長,多人開發時還很容易導致命名風格混亂,一個元素上使用的選擇器個數也可能越來越多。
歸根結底就是命名惹的禍
而CSS Module
就是在對className轉換的時候加入一定的規則,使得樣式名自動新增一個hash值,確保唯一性
// example.less
.title {
}
<div className={styles.title}>CSS Modules</div>;
//轉換後 =====>
<div class="title___3TqAx">title</div>
以上就是CSS Modules
的基本原理.更多用法可以參考:《Ant Design Pro - 樣式》
當然說那麼多,也是想證明一下classnames
的優秀
classnames語法
//基礎用法
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
// 各種各樣屬性結合
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'
// 一些不存在/空的屬性會自動忽略
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
//陣列會遍歷輸出
var arr = ['b', { c: true, d: false }];
classNames('a', arr); // => 'a b c'
//字串模板方式
let buttonType = 'primary';
classNames({ [`btn-${buttonType}`]: true });
通過狀態控制樣式的新增刪除,簡直不要太方便.從此告別removeClass
之類方法
結合React用法
動態控制按鈕樣式
constructor(arg){
super(arg)
this.state = {
isPressed: false,
isHovered: true
}
}
render(){
var btnClass = classNames({
btn: true,
'btn-pressed': this.state.isPressed,
'btn-over': !this.state.isPressed && this.state.isHovered
});
return(
<div>
<button className={btnClass}>按鈕</button>
</div>
)
}
// 輸出====> <button class="btn btn-over">按鈕</button>
結合`CSS Modules`用法
import classNames from 'classnames/bind';
let styles = {
key1: 'div',
key2: 'div1',
key3: 'div2'
};
let cssModulesClass = classNames.bind(styles);
let divClassName = cssModulesClass('key1', ['key2']);
<div className={divClassName}></div>// => "div div1"