在前端项目中写样式,往往会根据不同的情况给 DOM 元素不同的样式类来实现一些效果。用 React 项目举例,比如定义一个按钮:
<div className="btn">btn</div>
<div className="btn btn-disabled">btn</div>
<div className="btn btn-large">btn</div>
<div className="btn btn-primary">btn</div>
再比如定义一个元素是否被激活:
<div className="cls">element</div>
<div className="cls-active">element</div>
区分这种样式常规的写法:
<div className={active ? "cls" : "cls-active"}>element</div>
<div className={"btn btn-" + type}>btn</div>
这种写法让人感觉非常的啰嗦,不优雅。而且如果判断条件和存在的样式类特别多,会写的很长很恶心。
<button className="btn btn-primary btn-size-large btn-inline btn-ghost">btn</button>
如最常见的 Button 组件,它会有不同的样式、尺寸、显示方式、ghost 等等,这时候使用拼接和判断语句的方式都显得特别麻烦。
此时 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'
// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true }); // => 'foo bar baz quux'
// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
classnames 很好的解决了按需使用不同样式类的问题。下面是一个 React 例子:
// before
var Button = React.createClass({
// ...
render () {
var btnClass = 'btn';
if (this.state.isPressed) btnClass += ' btn-pressed';
else if (this.state.isHovered) btnClass += ' btn-over';
return <button className={btnClass}>{this.props.label}</button>;
}
});
// after
var classNames = require('classnames');
var Button = React.createClass({
// ...
render () {
var btnClass = classNames({
btn: true,
'btn-pressed': this.state.isPressed,
'btn-over': !this.state.isPressed && this.state.isHovered
});
return <button className={btnClass}>{this.props.label}</button>;
}
});
前后对比,明显优雅了很多。
回到按钮的问题,有了 classnames 就可以很好的解决样式类拼接麻烦的问题了。
const myClassName = classNames('btn', {
'btn-primary': false,
'btn-normal': true,
'btn-danger': false,
'btn-size-small': false,
'btn-size-middle': true,
'btn-size-large': false,
'btn-inline': false
})
return <button className={myClassName}>btn</button>
最后
墙裂推荐 classnames!