Css-In-Js实现classNames库源码解读

yizhihongxing

Css-In-Js实现classNames库源码解读

什么是Css-In-Js?

在传统的前端开发中,我们一般会把 HTML、CSS 和 JavaScript 三种语言分开编写,相互之间独立存在。但是,随着前端项目和业务逻辑的复杂,我们往往需要同时管理大量的样式和 JavaScript 代码,同时还要保证代码的可维护性和可复用性。Css-In-Js 就是为了解决这个问题而出现的一种解决方案。它将 CSS 样式直接写在 JavaScript 中,使得 CSS 和 JavaScript 可以更加紧密地结合,同时可以提供更多的高级特性,如动态样式、模块化组件、代码分割等。

什么是classNames库?

classNames 库是一个可以快速生成 CSS class 名字的 JavaScript 工具库,它的主要作用是将一组字符串格式的 class 名称连接成一个字符串,以逗号隔开。它的用法非常简单,只需要将每个 class 名称作为一个参数传入函数,并使用空格隔开即可:

var classNames = require('classnames');

classNames('foo', 'bar'); // 'foo bar'
classNames('foo', { bar: true }); // 'foo bar'
classNames({ 'foo-bar': true }); // 'foo-bar'
classNames({ 'foo-bar': false }); // ''
classNames(null, false, 'foo', undefined, 0, 1, { baz: null }, ''); // 'foo 1'

如何实现classNames库?

下面我们来看一下 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)) {
      classes.push(classNames.apply(null, arg));
    } else if (argType === 'object') {
      for (var key in arg) {
        if (hasOwn.call(arg, key) && arg[key]) {
          classes.push(key);
        }
      }
    }
  }

  return classes.join(' ');
}

首先,我们定义了一个 classNames 函数。该函数里面使用一个循环遍历传入的所有参数。对于每个参数,我们使用 typeof 来判断其类型。如果是字符串或数字,则将其直接加入 classNames 列表中。如果是数组,则递归地调用 classNames 函数,并将返回值存入 classNames 列表中。如果是对象,则遍历对象及其原型链中的所有属性,并只添加值为真的属性名称到 classNames 列表中。最终,我们使用 join 函数将 classNames 列表中的所有类名用空格连接起来,并返回连接后的字符串。

示例说明

下面我们将看两个示例,分别演示如何在 React 和 Vue 项目中使用 classNames 库:

示例1:在 React 项目中使用 classNames 库

import React, { Component } from 'react';
import classNames from 'classnames';

class Button extends Component {
  render() {
    const { small, primary, danger, className, children } = this.props;
    const classes = classNames(
      'btn',
      { 'btn-sm': small },
      { 'btn-primary': primary },
      { 'btn-danger': danger },
      className
    );
    return <button className={classes}>{children}</button>;
  }
}

export default Button;

在这个示例中,我们定义了一个 Button 组件,其中包含三个可能的属性:small、primary 和 danger,分别表示按钮的大小和颜色。我们使用 classNames 将这三个属性转化为对应的类名,然后将它们连成一个字符串,并存入 button 元素的 className 属性中。这样可以大大简化组件的使用方法,同时也可以保证渲染出来的 HTML 元素具有相应的样式效果。

示例2:在 Vue 项目中使用 classNames 库

<template>
  <div :class="classes">
    {{ message }}
  </div>
</template>

<script>
import classNames from 'classnames';

export default {
  name: 'MyComponent',
  props: {
    primary: Boolean,
    danger: Boolean,
    className: String
  },
  computed: {
    classes() {
      return classNames(
        { 'my-component': true },
        { 'my-component-primary': this.primary },
        { 'my-component-danger': this.danger },
        this.className
      )
    }
  },
  data() {
    return {
      message: 'Hello, World!'
    }
  }
}
</script>

在这个示例中,我们定义了一个名为 MyComponent 的 Vue 组件,其中包含两个可能的属性:primary 和 danger,分别表示组件的颜色。我们使用 computed 属性来将这两个属性转化为对应的类名,然后将它们连成一个字符串,并绑定到组件的 class 属性中。这样可以让组件具有相应的样式,同时也可以在页面中方便地定制样式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Css-In-Js实现classNames库源码解读 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • 浅谈如何通过node.js对数据进行MD5加密

    让我详细讲解一下如何通过Node.js对数据进行MD5加密的完整攻略。 什么是MD5加密 MD5加密是一种广泛用于数据安全领域的加密方式。它将任意长度的消息以一种不可逆的方式转换成一个长度固定的消息摘要(即16进制数字表示的32位字符串),以保证数据传输的安全性。 使用Node.js进行MD5加密 在Node.js中,可以通过crypto模块进行数据加密操作…

    node js 2023年6月8日
    00
  • JavaScript中的一些实用小技巧总结

    下面我会详细讲解JavaScript中的一些实用小技巧总结,主要包括以下内容: 数组操作技巧 对象操作技巧 字符串操作技巧 函数操作技巧 1. 数组操作技巧 1.1 数组去重 可以通过 Set 类型和 Array.from() 方法来去重数组: const arr = [1, 2, 2, 3, 3, 4]; const newArr = Array.from…

    node js 2023年6月8日
    00
  • 浅析 NodeJs 的几种文件路径

    下面是详细的攻略。 浅析 NodeJs 的几种文件路径 相对路径 相对路径是相对于当前文件所在目录的路径,即不包含完整的路径信息。在 Node.js 中,使用相对路径一般如下所示: const path = require(‘path’); const relativePath = ‘./utils/file.js’; const absolutePath …

    node js 2023年6月8日
    00
  • 利用VS Code开发你的第一个AngularJS 2应用程序

    以下是利用VS Code开发AngularJS 2应用程序的完整攻略: 背景介绍 AngularJS 2是一个强大的前端框架,在现代Web开发中被广泛使用。VS Code是一个轻量级的代码编辑器,支持很多编程语言,适合前端开发人员。在本攻略中,我们将介绍如何使用VS Code为AngularJS 2开发一个简单的应用程序。 环境准备 Node.js的安装:我…

    node js 2023年6月8日
    00
  • Node工程的依赖包管理方式

    Node工程的依赖包管理方式主要使用npm(Node Package Manager)进行管理。下面是npm的完整攻略: 安装npm 如果还没有安装npm,可以在终端或命令行中输入以下命令进行安装: $ sudo apt-get install npm 初始化npm 在项目的根目录下输入以下命令进行初始化: $ npm init 这时npm会要求你填写一些关…

    node js 2023年6月8日
    00
  • 总结几道关于Node.js的面试问题

    我将为你提供 “总结几道关于Node.js的面试问题”的完整攻略。Node.js是目前非常流行的一种服务器端运行环境,也成为了很多公司的首选技术之一。在面试过程中,Node.js必然会成为面试官所重点问及的内容之一。以下详细讲解关于Node.js的一些面试问题,供你参考: 如何阻止Node.js程序在崩溃时停机? 这是一个经典问题,面试官想考察你是否有Eve…

    node js 2023年6月8日
    00
  • 详解使用nodeJs安装Vue-cli

    请跟我一起来详解使用Node.js安装Vue-cli的完整攻略。 1. 安装Node.js Node.js是一个基于Chrome V8引擎的JavaScript运行时环境,可以用于服务器端JavaScript环境的搭建。因为Vue-cli是基于Node.js开发的,所以安装Node.js是使用Vue-cli的前提。Node.js支持多操作系统安装,例如Win…

    node js 2023年6月8日
    00
  • JS解决 Array.fill()参数为对象指向同一个引用地址的问题

    JS中,数组的fill()方法可以用来将一个固定值填充到数组中的每一个元素上。但是当传递的参数为对象时,会出现指向同一个引用地址的问题。因此,为了解决这个问题,我们可以采取以下几种方案。 方案一:使用 ES6 中的 Array.from() 方法 在 ES6 中,Array.from() 方法可以将任何可迭代对象转换为一个数组。因此,我们可以先使用该方法生成…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部