classnames用法/源码分析及工具

classnames的基础用法归集
  1. classnames这个插件在react项目业务中用的相对来说是比较多的,那这个插件是用来干什么的呢,它是用来合并类名的,存在多个类名变量时,想添加到对应的元素中,是可以采用类名,这种插件在react相关业务使用比较多,因为react代码的业务场景,非常适合变量和元素的绑定,而classnames很好迎合react的相关的业务场景。那我们先来看classnames相关用法吧
  2. 基础用法
  • classnames这个可以是两个参数以上,类型可以字符串或者对象,如果是字符串,自动合并成多个类名,如果是对象呢?
  • classnames({a:true}, {b:true})只有a和b属性值是布尔值,只有为true时,类才会显示成功

  • 它还能通过es6中的模板字符串去绑定类名:let buttonType = 'primary';classNames({ [btn-${buttonType}]: true };

  • 与react相关组件,基础用法:

        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>;
    		}
    	}
    
    • 可以通过classnames/bind去实现类名对象合并
    	import { Component } from 'react';
    	import classNames from 'classnames/bind';
    	import styles from './submit-button.css';
    
    	let cx = classNames.bind(styles);
    
    	export default class SubmitButton extends Component {
    	render () {
    		let text = this.props.store.submissionInProgress ? 'Processing...' : 'Submit';
    		let className = cx({
    		base: true,
    		inProgress: this.props.store.submissionInProgress,
    		error: this.props.store.errorOccurred,
    		disabled: this.props.form.valid,
    		});
    		return <button className={className}>{text}</button>;
    	}
    	};
    
classnames的源码实现
  1. 先将classnames源码进行clone下来分析一下它的结构,第一步先找package.json文件,关键要看这几个属性,main,types,devDependencies,Dependencies,scripts这几大属性
  2. main属性源码包的入口,业务中通过require/import引入时的主入口文件,scripts里面配置了可能存在调试源码相关命令,devDependencies,Dependencies代表插件中使用了哪些依赖包
  3. 通过main中看到index.js文件中,通过源码包中分析得知,index.js是源码的code,不是编译后的code
  4. 接下来我们主要分析index.js中的源码,在这个源码中只有50行左右非常精简啦
  • 采用了自执行的函数,避免变量污染冲突;采用严格模式
  • 它的源码方法是classnames这个方法,先定一义一个var classes = []数组对象,后遍历arguments参数对象,先把不存在的参数或者参数类型false/undefined/null给过滤掉,接下来进行判断类型,string/number类型,直接装到数组中,判断数组进行递归,判断纯对象字面量,就遍历对象,将对象的key值是否存在,存在装到classes数组对象中,不是存对象字面量,转换成string类型装到数组中,这是classnames方法实现的一个思路,下面附一源码
	function classNames() {
   	var classes = [];

   	for (var i = 0; i < arguments.length; i++) {
   		var arg = arguments[i];
   		if (!arg) continue;

   		var argType = typeof arg;

   		if (argType === 'string' || argType === 'number') {
   			classes.push(arg);
   		} else if (Array.isArray(arg)) {
   			if (arg.length) {
   				var inner = classNames.apply(null, arg);
   				if (inner) {
   					classes.push(inner);
   				}
   			}
   		} else if (argType === 'object') {
   			if (arg.toString === Object.prototype.toString) { // 【object object】
   				for (var key in arg) {
   					if (hasOwn.call(arg, key) && arg[key]) {
   						classes.push(key);
   					}
   				}
   			} else {
   				classes.push(arg.toString());
   			}
   		}
   	}

   	return classes.join(' ');
   }
  • 代码还做了一个引入环境的判断,commonjs/amd/window模块环境引入,其实这就是一个umd一个的写法哟
	if (typeof module !== 'undefined' && module.exports) {
   	classNames.default = classNames;
   	module.exports = classNames;
   } else if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {
   	// register as 'classnames', consistent with npm package name
   	define('classnames', [], function () {
   		return classNames;
   	});
   } else {
   	window.classNames = classNames;
   }
  • 当然还可以采用打包工具直接去打包,也就没必要去写这个模块的环境的代码咯。。。
  1. 上面我们将classnames函数分析了一遍,接下我们bind.js文件中的源码就是引入一个this的使用,其他的源码逻辑几乎一致
  2. dedupe.js这个文件中对源码再进行一步修改,进行封装,采用了类多态的一个实现思路
  3. 其他工具包,通过查看package.json,看到两个比较陌生的包的benchmarkbrowserify,我们先看这两个包是用来干嘛的吧。
  • 从官方文档,我们得知,benchmark用来做基准性能测试的,如果想要了解怎么去做基准性能测试,请点击, 看博客,感兴趣请自行研究
  • browserify从博客中,它是一款前端基于浏览器的打包工具,这款工具年代十足,此地不过多赘述了,感兴者,自行研究。
总结
  • 从文档中熟悉了classnames的基础用法,这是一款与react项目结合比较紧密的插件
  • 从dedupe.js中学习了多态的实现方案
  • 还了解了benchmark是一款基准性能测试工具,还知道了browserify是款基于浏览器端的打包工具

参考文档

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值