首页 > 其他分享 >ClassNames库详解

ClassNames库详解

时间:2023-02-06 23:44:41浏览次数:49  
标签:classNames classnames ClassNames 详解 toString arg var classes

简述

  ClassNames是一个用于有条件处理classname字符串连接的库,非常好用~。

  简单来说就是动态地去操作类名,把符合条件的类名粘在一起。

安装(使用npm)

npm install classnames

引入

在nodejs里引入

var classNames = require('classnames');

在js里引入

import classnames from 'classnames'

基本使用

普通字符串粘合

  将参数拼接为字符串,中间用空格分开

classNames('foo', 'bar'); // => 'foo bar'

带条件的类参数

  这里第二个参数是对象类型,键值为true,则粘合进classname里

classNames('foo', { bar: true }); // => 'foo bar'

  若为false,则不粘进去

classNames('foo', { bar: false }); // => 'foo'

参数类型是数组

var arr = ['b', { c: true, d: false }];
classNames('a', arr); // => 'a b c'

特别注意

  null和undefiend会被忽略

classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1'

在react中优雅地使用classnames

  下面这段代码,通过if-else判断state的状态,动态选择btnClass的具体值

class Button extends React.Component {
  // ...
  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>;
  }
}

  现在用classnames来做,btnClass就可以边成一个对象,通过键值的条件确定最终生成的classname

import classnames from '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源码:

function classNames() {
  var classes = [];//用于存储生成的类名

  for (var i = 0; i < arguments.length; i++) {//遍历classnames的所有参数
    var arg = arguments[i];
    if (!arg) continue;

    var argType = typeof arg; //拿到每一个参数的类型

    if (argType === "string" || argType === "number") { //如果是字符串或数字就直接加到classes数组里
      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") { //如果是对象且有自定义的toString方法,则调用toString方法添加到classes对象里,if里面的表达式下面会详细介绍
      if (
        arg.toString !== Object.prototype.toString &&
        !arg.toString.toString().includes("[native code]") 
      ) {
        classes.push(arg.toString());
        continue;
      }

      for (var key in arg) {
        if (hasOwn.call(arg, key) && arg[key]) { //如果键值为真就加进classes数组里
          classes.push(key);
        }
      }
    }
  }

  return classes.join(" ");// 最后在中间加上空格转成字符串
}

  arg.toString !== Object.prototype.toString啥意思?

  我们知道所有js对象都继承Object对象,即都继承toString方法,这个表达式的意思就是这个对象的toString方法不是继承自Object.prototype

  arg.toString.toString().includes("[native code]") 啥意思?

  我们首先要知道toString方法的一些知识:当我们对一个自定义函数调用toString()方法时,可以得到该函数的源代码;如果对内置函数使用toString()方法时,会得到一个'[native code]'字符串。因此,可以使用toString()方法来区分自定义函数和内置函数,注意是对函数调用toString()方法,所以我们通过对toString函数调用toString方法,就能得知这个toString是内置的,还是自定义的

  这里两个表达式连起来的意思就是:现在这个类有toString方法,而且还是自定义的

References

https://www.npmjs.com/package/classnames?activeTab=readme

http://www.npmdoc.org/classnameszhongwenwendangclassnames-jszhongwenjiaochengjiexi.html

https://juejin.cn/post/7178760381324591163

https://www.cnblogs.com/xiaohuochai/p/5557387.html

标签:classNames,classnames,ClassNames,详解,toString,arg,var,classes
From: https://www.cnblogs.com/CNLayton/p/17097049.html

相关文章

  • File类详解--Java基础083
    packagecom.sqf.file;importjava.io.File;importjava.io.IOException;/*File类的构造方法:File(Stringpathname)指定文件或者文件夹的路径创建一个File文件......
  • seaborn详解
    #coding=utf-8importseabornassnsimportnumpyasnpimportmatplotlibasmplimportmatplotlib.pyplotaspltdefsinplot(flip=1):x=np.linspace(0,14,100)......
  • pannas详解
    #coding=utf-8'''pannas的函数作用;read_csv(文件的路径)读取文件<class'pandas.core.frame.DataFrame'>(read_csv返回的对象)对象的方法与属性:属......
  • 详解Spring AOP自定义可重复注解没有生效问题
    目录1.问题背景2.不啰嗦,上代码3.问题排查3.1是不是切点写得有问题,于是换成如下形式:3.2是不是使用的地方不是代理对象4.问题原因 1.问题背景工作中遇......
  • tensorflow中slim详解
    1.变量的定义 from__future__importabsolute_importfrom__future__importdivisionfrom__future__importprint_functionimporttensorflowastfslim=tf.contrib......
  • python3中zip详解
    描述zip()函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象......
  • 一文详解TensorFlow模型迁移及模型训练实操步骤
    摘要:本文介绍将TensorFlow网络模型迁移到昇腾AI平台,并执行训练的全流程。然后以TensorFlow1.15训练脚本为例,详细介绍了自动迁移、手工迁移以及模型训练的操作步骤。本文分......
  • 一文详解TensorFlow模型迁移及模型训练实操步骤
    摘要:本文介绍将TensorFlow网络模型迁移到昇腾AI平台,并执行训练的全流程。然后以TensorFlow1.15训练脚本为例,详细介绍了自动迁移、手工迁移以及模型训练的操作步骤。本文......
  • JVM垃圾回收机制,万字详解
    JVM垃圾回收机制jvm的基本组成虚拟机的组成所谓java能实现跨平台,是因为在不同平台上运行不同的虚拟机决定的,因此java文件的执行不直接在操作系统上执行,而是通过jvm虚拟机执......
  • Redis详解
    Redis配置ymlspring:redis:host:82.157.248.243#host地址port:6379#地址端口号password:#密码database:......