「我正在参与掘金会员专属活动-源码共读第一期,点击参与」
本篇文章介绍的是
classnames
,一个简单的JavaScript
工具,作用是将classnames
聚集在一起。
安装
# via npm
npm install classnames
# via Bower
bower install classnames
# or Yarn
yarn add classnames
使用
var classNames = require('classnames');
classNames('foo', 'bar'); // => 'foo bar'
还可以直接将index.js
(dedupe.js
后续提到的去重版本)通过script
标签引入到页面,全局有个classNames
方法可以调用。如果你使用的是RequireJS
,定义一下模块。
classNames
方法会处理若干个字符串类型或者对象参数,foo
是{foo: true}
的简写,如果参数的值是falsy
,最终输出不会包含该值。
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': false }); // => ''
// 其他的falsy值会被忽略的情况
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'
数组会按照以上规则递归扁平化处理
var arr = ['b', { c: true, d: false }];
classNames('a', arr); // => 'a b c'
ES6
中的计算属性
let buttonType = 'primary';
classNames({ [`btn-${buttonType}`]: true }); // => 'btn-primary'
当然还有备用的去重版本
var classNames = require('classnames/dedupe');
classNames('foo', 'foo', 'bar'); // => 'foo bar'
classNames('foo', { foo: false, bar: true }); // => 'bar'
使用css-modules
用的版本,根据传入的classNames
得到对应的值。平时没有使用css-modules
,所以在这里就不展开了。
当然还能在React.js
里使用
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 <button className={btnClass}>{this.props.label}</button>;
}
}
看到这里,Vue
的小伙伴会不会联想到在Vue.js
里使用的:class
动态绑定类名。
<div :class={isActive ? 'active': ''}></div>
这句代码的意思是: 如果isActive
为真类名就是active
,否则为空字符串。和classNames
函数是不是有异曲同工之妙。
Polyfill
:Array.isArray
兼容老版本的浏览器垫片
源码
了解一个项目的最直接简单的方式就是看package.json
。
"main": "index.js"
通过这个配置项找到源码入口。
首先定义了在代码13行定义了classNames
函数,48行开始做了各个模块的兼容处理。
核心看classNames
函数
- 声明
classes
数组用来存储结果 - 遍历了
arguments
内置参数。如果为假值直接跳过 - 得到每个参数的类型,如果是字符串类型或数字类型,直接添加到
classes
里 - 如果参数是数组,做递归处理
classNames.apply(null, arg)
自调用 - 如果参数是对象:考虑
toString()
是否是自定义的如果是的将toString()
结果添加到classess
里(这里为了避免循环的情况考虑toString
直接使用toString
),否则,遍历对象将对象的自有属性加入classes
里。 - 最后将数组元素通过空格拼接
结束语
整个源码还是很通俗易懂,在我们阅读的时候其实还是很轻松的,如果我们自己来实现的话,还是一个很困难的事情的。代码呈现在我们面前,就很顺利的跟着作者的思路走下来,如果自己实现就会出现磕磕绊绊,所以呢,多学习源码还提高代码的素质很有必要的。