源码学习 -- classnames

classnames 是公司项目中使用较频繁的一个库,因为能方便动态切换 class 名称。

放下对比大家感受下~

	<!-- before -->
	let clsName = 'conetnt'
    
	if (showContent) {
	  clsName += ' show'
	} else {
	  clsName += ' hide'
	}
    
	if (needMargin) clsName += ' add-margin'
    
	return <div className={clsName} />
    
	<!-- 使用 classnames 后 -->
	return <div className={classnames('content', { show: showContent, hide: !showContent, 'add-margin': needMargin })} />

又比如自己封装的业务组件,调用方经常需要传入自定义 class 类名,使用 classnames 的话是这个样子:

	// 假设 clsName 为父组件传入的自定义类名,可选
	<div className={classnames('self-classname', { [clsName]: !!clsName })} />

以上 classnames 可以根据 truly 值动态选择拼接 class 名称,在前端开发中是很方便的。

使用多了逐渐对 classnames 产生了好奇:它的内部是如何运行的?🤔

github 上查看源码后也从中学到了一些东西 👍 ,分享给大家:

	// 保存 object 的 hasOwnProperty 方法引用
	var hasOwn = {}.hasOwnProperty
	
	function classNames() {
		var classes = []
	
		for (var i = 0; i < arguments.length; i ++) {
			var arg = arguments[i]
			// 跳过 falsy 参数值
			if (!arg) continue

			var argType = typeof arg
			
			if (argType === 'string' || argType === 'number') {
				// 如果某个参数是 string 或 number 类型,直接放入 classes 数组
				classes.push(arg)
			} else if (Array.isArray(arg) && arg.length) {
				// 若某个参数是 数组 类型,将数组里的参数传入 classNames 再调用一次并获取返回值
				var inner = classNames.apply(null, arg)
				if (inner) classes.push(inner)
			} else if (argType === 'object') {
				if (arg.toString !== Object.prototype.toString) {
					// 若某元素有自定义 toString 方法,调用该方法并将返回值存入 classes
					classes.push(arg.toString())
				} else {
					for (var key in arg) {
						// 若某元素为对象,遍历该对象的 key,只取元素自身不为 falsy 的 key 放入 classes
						if (hasOwn.call(arg, key) && arg[key]) classes.push(key)
					}
				}
			}
		}

		// 将 classes 元素通过 ' ' 空格拼接后返回,即拼接后的 class 名称
		return classes.join(' ')
	}

方法测试截图:

在这里插入图片描述
了解源码内部运行机制,能让我们在使用的时候明确结果是如何产生的,同时哪些使用方法是不适合的等等~ 🤗

– End –

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值