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

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之readline模块的使用详解

    下面是关于“Node.js之readline模块的使用详解”的完整攻略。 什么是readline模块? readline模块是Node.js中提供的一个实用模块,可以用来从流(如stdin)读取数据,并将数据输出到流(如stdout)中。它主要用于命令行交互式应用程序的开发。 安装readline模块 如果你使用的是Node.js的版本较为新的话,那么rea…

    node js 2023年6月8日
    00
  • 学习Node.js模块机制

    学习Node.js模块机制可以分为以下几个步骤: 1. 了解模块机制概念 在Node.js中,每个文件都被视为一个模块,模块机制通过exports对象暴露模块中的函数、变量等,使其可在其他模块被调用。模块机制使用CommonJS规范来实现模块化。 2. 导出模块 要导出一个模块,需要用module.exports 或 exports 将需要导出的函数、变量等…

    node js 2023年6月8日
    00
  • node.js中fs文件系统目录操作与文件信息操作

    下面是关于在Node.js中进行fs文件系统目录操作与文件信息操作的完整攻略。 1. fs模块的引入 在Node.js中,进行fs文件系统目录操作与文件信息操作,需要先引入fs模块,代码如下: const fs = require(‘fs’); 2. 目录操作 2.1 创建目录 可以使用fs模块中的mkdir函数来创建目录,其语法如下: fs.mkdir(p…

    node js 2023年6月8日
    00
  • node.js实现多图片上传实例

    具体的攻略如下: 1. 安装依赖 在开始项目前,需要先安装所需的依赖: npm install express multer 其中,express是Node.js的Web框架,用于创建服务器;multer是Node.js的一个中间件,用于处理HTTP上传请求,支持多文件上传。 2. 编写HTML页面 需要先编写一个HTML页面,用于展示表单和上传控件。以下为…

    node js 2023年6月8日
    00
  • JS 使用for循环遍历子节点查找元素

    下面是使用for循环遍历子节点查找元素的完整攻略。 1. 获取父节点和子节点 首先,我们需要使用 document.getElementById()方法或其他方法获取到父节点,例如: const parent = document.getElementById(‘parentNode’); 然后,我们需要获取到父节点的所有子节点,可以使用 childNode…

    node js 2023年6月8日
    00
  • Lua表达式和控制结构学习笔记

    Lua表达式和控制结构学习笔记 简介 本文主要介绍Lua的表达式和控制结构,能够让读者了解Lua的基本语法结构。 内容 Lua表达式 Lua表达式是由数字、字符串和运算符等基本元素组成的。 数字 Lua中的数字可以是整数或浮点数,可以使用科学计数法来表示。例如: print(123) –> 123 print(1.23) –> 1.23 pr…

    node js 2023年6月8日
    00
  • 三分钟教你用Node做一个微信哄女友(基友)神器(面向小白)

    让我来详细讲解“三分钟教你用Node做一个微信哄女友(基友)神器(面向小白)”的完整攻略。 首先,我们需要了解这个神器的基本功能:在微信公众号上面输入指定的关键词,就会自动回复指定的消息。比如说,当我在公众号上输入“爱你”,就能够自动回复“我也爱你啊”之类的消息。接下来,我们就可以按照以下步骤来完成这个神器的制作。 步骤一:注册微信公众号并开启开发者模式 首…

    node js 2023年6月8日
    00
  • 详解用Node.js实现Restful风格webservice

    详解用Node.js实现Restful风格webservice 在本文中,我们将详细讲解如何使用Node.js实现Restful风格的webservice。Node.js是一个基于Chrome的JavaScript运行环境,可以使用JavaScript开发服务器端应用程序。Restful风格的webservice是一种基于HTTP通信协议,使用Web标准来提…

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