React 之 CSS编写方式

news2024/11/30 6:51:04

一、概述

整个前端已经是组件化的天下,而CSS的设计就不是为组件化而生的,所以在目前组件化的框架中都在需要一种合适的CSS解决方案

在组件化中选择合适的CSS解决方案应该符合以下条件:

  • 可以编写局部css:css具备自己的具备作用域,不会随意污染其他组件内的元素;

  • 可以编写动态的css:可以获取当前组件的一些状态,根据状态的变化生成不同的css样式;

  • 支持所有的css特性:伪类、动画、媒体查询等;

  • 编写起来简洁方便、最好符合一贯的css风格特点;

  • 等等...

React官方并没有给出在React中统一的样式风格:
  • 由此,从普通的css,到css modules,再到css in js,有几十种不同的解决方案,上百个不同的库

  • 大家一直在寻找最好的或者说最适合自己的CSS方案,但是到目前为止也没有统一的方案

二、写法 - 内联样式CSS

1. 概念

内联样式是官方推荐的一种css样式的写法:
  • style 接受一个采用小驼峰命名属性的 JavaScript 对象 ( { {} } ),而不是 CSS 字符串

  • 并且可以引用state中的状态来设置相关的样式

2. 优点

  • 内联样式, 样式之间不会有冲突

  • 可以动态获取当前state中的状态

3. 缺点

  • 写法上都需要使用驼峰标识

  • 某些样式没有提示

  • 大量的样式, 代码混乱

  • 某些样式无法编写(比如伪类/伪元素)

官方是希望内联合适和普通的css来结合编写

4. 代码

import React, { PureComponent } from 'react';

export class App extends PureComponent {
  getPColor() {
    return 'purple';
  }
  getStyle() {
    return {
      color: 'yellow',
      fontSize: '50px'
    };
  }
  render() {
    const hSize = 40;
    return (
      <div>
        {/* 1. 直接写入 */}
        <h1 style={{ color: 'red' }}>React App</h1>

        {/* 2. 变量控制 */}
        <h2 style={{ fontSize: `${hSize}px` }}>React App</h2>

        {/* 3. 三元表达式 */}
        <p style={{ color: 30 > 40 ? 'red' : 'blue' }}>React content</p>

        {/* 4. 单个样式函数 */}
        <p style={{ color: this.getPColor() }}>React content</p>

        {/* 5. 样式函数 */}
        <p style={this.getStyle()}>React content</p>
      </div>
    );
  }
}

export default App;

三、写法 - 普通CSS文件

普通的css通常会编写到一个单独的文件,之后再进行引入
这样定义的css文件,不管在哪里引入,都是全局的css
  • 这样的编写方式和普通的网页开发中编写方式是一致的

  • 如果按照普通的网页标准去编写,那么也不会有太大的问题

  • 但是组件化开发中希望组件是一个独立的模块,即便是样式也只是在自己内部生效,不会相互影响

  • 但是普通的css都属于全局的css,样式之间会相互影响

  • 这种编写方式最大的问题是样式之间会相互层叠掉

css代码

.notice{
  /* 使用传递过来的变量 */
  color: var(--color);
  font-size: var(--fontSize);
  background-color: black;
}

组件使用

import React, { PureComponent } from 'react';
// 导入样式
import './style.css';

export class index extends PureComponent {
  render() {
    const fontSize = '40';
    return (
      <div>
        {/* 传递变量到css文件 */}
        <h1 className='notice' style={{ '--fontSize': `${fontSize}px`, '--color': 'pink' }}>
          React title
        </h1>
      </div>
    );
  }
}

export default index;

四、写法 - CSS Module

css modules确实解决了局部作用域的问题,也是很多人喜欢在React中使用的一种方案。
  • css modules并不是React特有的解决方案

  • 而是所有使用了类似于webpack配置的环境下都可以使用的

  • 如果在其他项目中使用它,那么需要进行配置

  • 比如配置webpack.config.js中的modules: true

  • React的脚手架已经内置了css modules的配置:

  • .css/.less/.scss 等样式文件都需要修改成 .module.css/.module.less/.module.scss

  • 之后就可以引用并且进行使用了

css代码

文件名称得改 => 比如 App.module.css
.title{
  color: red;
  font-size: 32px;
}

.content{
  color: blue;
  font-size: 24px;
}

组件使用

import React, { PureComponent } from 'react';
// 1. 这样导入
import appStyle from './App.module.css';

export class App extends PureComponent {
  render() {
    return (
      <div>
        {/* 2. 这样使用,可使用多个 */}
        <h1 className={`${appStyle.title} ${appStyle.text}`}>React title</h1>
        <h2 className={appStyle.content}>React content</h2>
      </div>
    );
  }
}

export default App;

缺点

  • 引用的类名,不能使用连接符(.home-title),在JavaScript中是不识别的

  • 所有的className都必须使用{style.className} 的形式来编写

  • 不方便动态来修改某些样式,依然需要使用内联样式的方式

五、写法 - Less的编写方式

使用less需要进行配置
1. 配置webpack,可以通过npm run eject => 暴露出webpack的配置
2. 使用carco => create-react-app confg 工具,进行配置

使用工具 - craco

安装

npm install @craco/craco => 安装工具
npm install craco-less => 加载less样式和修改变量

配置

package.js启动命令修改,用craco启动
  "scripts": {
    "serve": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },
新建 craco.config.js 文件
const CracoLessPlugin = require('craco-less');

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          // 注入变量
          lessOptions: {
            modifyVars: { '@primary-color': '#1DA57A' },
            javascriptEnabled: true
          }
        }
      }
    }
  ]
};
重新启动项目 => npm run serve

less代码

创建App.less 文件,less中可以使用连接符(.home-title)
@redColor:red;
@purpleColor:purple;

.box{
  .title{
    font-size: 20px;
    color: @redColor;
    &-active{
      color: @purpleColor;
    }
  }
  .content{
    font-size: 16px;
    // 使用craco.config.js中配置的@primary-color
    color: @primary-color;
  }
}

组件使用

import React, { PureComponent } from 'react';
import styles from './App.module.less';

export class App extends PureComponent {
  render() {
    return (
      <div className={styles.box}>
        <h2 className={`${styles.title} ${styles['title-active']}`}>title</h2>
        <p className={`${styles.content}`}>content</p>
      </div>
    );
  }
}

export default App;

六、写法 - CSS in JS

1. 前言

概念

官方文档也有提到过CSS in JS这种方案:
  • “CSS-in-JS” 是指一种模式,其中 CSS 由 JavaScript 生成而不是在外部文件中定义

  • 注意此功能并不是 React 的一部分,而是由第三方库提供

  • CSS-in-JS的模式就是一种将样式(CSS)也写入到JavaScript中的方式

  • 并且可以方便的使用JavaScript的状态

  • CSS-in-JS通过JavaScript来为CSS赋予一些能力

  • 包括类似于CSS预处理器一样的样式嵌套、函数定义、逻辑复用、动态修改状态等等

  • React有被人称之为 All in JS

  • CSS-in-JS是React编写CSS最为受欢迎的一种解决方案

目前比较流行的CSS-in-JS的库 :
  • styled-components - 更流行

  • emotion

  • glamorous

安装styled-components => npm install styled-components

题外话 - 标签模版字符串

安装vscode插件

插件 : vscode-styled-components

2. 基本使用

创建style.js文件
import styled from 'styled-components';
// 这里可以单独创建一个文件,设置统一变量
const color = 'red'

/**
 * AppWrapper
 * 用标签模版字符串来调用该函数 => 类似styled.div()这样的调用
 * 该函数返回一个React组件
 */
export const AppWrapper = styled.div`
  .box {
    .title {
      color: ${color};
      cursor: pointer;
      &:hover {
        color: orange;
      }
    }
    .content {
      color: blue;
    }
  }
`;
组件使用
import React, { PureComponent } from 'react';
import { AppWrapper } from './style.js';

export class App extends PureComponent {
  render() {
    return (
      // <div className='app'> 变成了下面的写法,因为在style.js中已经写了
      <AppWrapper>
        <div className='box'>
          <h2 className='title'>title</h2>
          <p className='content'>content</p>
        </div>
      </AppWrapper>
      // </div>
    );
  }
}

export default App;
效果

3. 传递props

可以有效的解决动态样式的问题
组件传递,在样式中通过函数拿到传入的值,如果未传入,会使用默认的值
组件使用
import React, { PureComponent } from 'react';
import { AppWrapper } from './style.js';

export class App extends PureComponent {
  constructor() {
    super();

    this.state = {
      color: 'green',
      fontSize: '60'
    };
  }
  render() {
    const { color, fontSize } = this.state;
    return (
      // 这样写的话,AppWrapper组件就可以接收到color和fontSize这两个属性了
      <AppWrapper color={color} fontSize={fontSize}>
        <div className='box'>
          <h2 className='title'>title</h2>
          <p className='content'>content</p>
        </div>
      </AppWrapper>
    );
  }
}

export default App;
style.js文件
import styled from 'styled-components';

export const AppWrapper = styled.div`
  .box {
    .title {
      /* props会作为一个函数的参数,在这里拿到 */
      color: ${(props) => props.color};
      cursor: pointer;
      &:hover {
        color: orange;
      }
    }
    .content {
      font-size: ${({ fontSize }) => fontSize}px;
      color: blue;
    }
  }
`;

4. 设定attrs

可对传过来的值进行处理,attr( 这里是一个函数,后返回一个对象 )
import styled from 'styled-components';

export const AppWrapper = styled.div.attrs((props) => ({
  // 通过props拿到传入的值
  // 并且可以做一些处理,color,可以通过props.color,并且当color没有传入时,可以设置默认值
  color: props.color || 'red',
  // 还可以直接定义一些默认值
  border: '1px solid red'
}))`
  .box {
    .title {
      /* 使用的是上方attrs中处理过的值 */
      color: ${(props) => props.color};
      cursor: pointer;
      /* 使用attrs中定义的值 */
      border: ${(props) => props.border};
    }
    .content {
      font-size: ${({ fontSize }) => fontSize}px;
      color: blue;
    }
  }
`;

5. styled高级特性

七、添加class

1. vue中

2. react中

React在JSX给了开发者足够多的灵活性,但是一旦动态的类多了后,就不太友好了
render() {
  const index = 3;
  return (
    <div className={styles.box}>
      {/* 使用 && */}
      <h2 className={`${styles.title} ${index === 3 && styles['title-active']}`}>title</h2>
      {/* 使用 三元运算符 */}
      <p className={`${styles.content} ${index === 2 ? styles['title-active'] : ''}`}>content</p>
    </div>
  );
}
可使用一个第三方的库: classnames => npm i classnames
import React, { PureComponent } from 'react';
import styles from './App.module.less';

// 1. 使用classnames
import classnames from 'classnames';

export class App extends PureComponent {
  render() {
    const index = 3;
    return (
      <div className={styles.box}>
        {/* 使用 && */}
        <h2 className={`${styles.title} ${index === 3 && styles['title-active']}`}>title</h2>
        {/* 使用 三元运算符 */}
        <p className={`${styles.content} ${index === 2 ? styles['title-active'] : ''}`}>content</p>

        {/* 2. 使用classnames,调用classnames()函数即可 */}
        <p
          className={classnames('aaa', 'bbb', styles.title, {
            [styles['title-active']]: index === 3
          })}>
          content
        </p>
      </div>
    );
  }
}

export default App;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/741191.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实现一个vscode插件:打开多个vscode项目时根据.nvmrc文件自动切换nvm

开发背景与最终功能 需要维护一些老项目&#xff0c;同时开发新项目时&#xff0c;切换nvm很烦人 最终实现vscode插件&#xff1a;每个vscode实例打开一个项目&#xff0c;切换vscode实例时能自动切换版本&#xff08;需要项目根目录有一个.nvmrc文件&#xff09; 插件下载 …

nextjs13中cssModule设置子标签的样式

前言 最近在学习nextjs中发现&#xff0c;如果在cssModule文件中直接设置子标签的样式比较麻烦&#xff0c;最后在网上看到一种方式可以解决&#xff0c;方式如下。 ps: 此方式不一定最优&#xff0c;因为在我看来此代码耦合性太高了&#xff0c;看着不太舒适&#xff0c;因为…

保姆级指南|APP原型设计怎么做?手把手教学超详细!

在数字化产品研发过程中&#xff0c;原型设计扮演着至关重要的角色。不夸张的说&#xff0c;产品原型很大程度决定了最终产品的成功与否。随着主流产品载体的更迭和发展&#xff0c;原型设计也在不断的演进。也产生了网页原型设计&#xff0c;桌面端app原型设计&#xff0c;移动…

PyTorch模型创建与nn.Module

文章和代码已经归档至【Github仓库&#xff1a;https://github.com/timerring/dive-into-AI 】或者公众号【AIShareLab】回复 pytorch教程 也可获取。 文章目录 模型创建与nn.Modulenn.Module 总结 模型创建与nn.Module 创建网络模型通常有2个要素&#xff1a; 构建子模块拼接…

Redis 优惠卷秒杀(二) 异步秒杀、基于Stream的消息队列处理

目录 基于Stream的消息队列 Redis优化秒杀 登录头 改进秒杀业务&#xff0c;调高并发性能 Redis消息队列实现异步秒杀 ​编辑基于List结构模拟消息队列 基于PuSub的消息队列 ​编辑 基于Stream的消息队列 Redis消息队列 基于Stream的消息队列 Redis优化秒杀 登录头 改…

skywalking安装

目录 skywalking部署示意图 server安装 裸机安装 docker单节点安装 docker集群安装 k8s安装 helm安装(官方) k8s yaml安装 动态配置安装 client agent安装 skywalking部署示意图 skywalking ui - web界面管理程序oap server - skywalking服务程序nacos - skywalking集…

数字孪生水务系统可视化管理平台有效缓解城市供水压力

针对传统自来水厂供水水质安全隐患大&#xff0c;运行管理落后等问题&#xff0c;基于数字孪生技术构建全厂三维立体模型,在电脑前就可以掌握全厂管线、设备运行情况,遇到预案中的突发事件还可以给出辅助决策方案。从根本上有效提高水厂运行管理效率,增强对水质变化的应对能力,…

分析shein独立站成功的原因

近年来&#xff0c;Shein独立站在快时尚领域声名鹊起&#xff0c;成为许多时尚消费者的首选网站。面对激烈的竞争&#xff0c;它依然能够站稳脚跟并不断壮大。那么&#xff0c;Shein独立站成功的原因是什么呢&#xff1f; Shein独立站——以消费者为中心的运营模式 Shein独立站…

【Python】Locust持续优化:InfluxDB与Grafana实现数据持久化与可视化分析

在进行性能测试时&#xff0c;我们需要对测试结果进行监控和分析&#xff0c;以便于及时发现问题并进行优化。 Locust在内存中维护了一个时间序列数据结构&#xff0c;用于存储每个事件的统计信息。 这个数据结构允许我们在Charts标签页中查看不同时间点的性能指标&#xff0c…

java中使用HttpRequest发送请求调用自己的接口

(539条消息) java中使用HttpRequest发送请求_java httprequest_thankful_chn的博客-CSDN博客 <dependency><groupId>com.github.kevinsawicki</groupId><artifactId>http-request</artifactId><version>5.6</version></dependenc…

华为云-hcip笔记-网络服务规划

华为云-hcip笔记-网络服务规划 网络服务规划 安全组和网络ACL 网络ACL对子网进行防护&#xff0c;安全组是对ECS进行防护。 对等连接VPC peering 两个vpc之间的网络连接&#xff0c;用户可以使用私有ip地址在两个vpc之间进行通信。 同账号中对等连接自动接受&#xff0c;跨…

【JavaEE】JVM的组成及类加载过程

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: JavaEE初阶 本文我们主要讲解一下面试中常见的问题&#xff0c;如果想深入了解&#xff0c;请看一下《Java虚拟机规范》这本书 目录 文章目录 一、JVM简介 二、JVM整体组成 2.1 运行时数据区组成 2.2…

【LeetCode周赛】2022上半年题目精选集——数学

文章目录 2183. 统计可以被 K 整除的下标对数目⭐⭐⭐⭐⭐思路——数论&#xff08;一个数乘上另一个数x是k的倍数&#xff0c;x最小是多少&#xff1f;&#xff09;代码1——统计每个数的因子代码2——统计k的因子 2245. 转角路径的乘积中最多能有几个尾随零思路&#xff08;因…

探索全球市场:初创品牌海外营销策略解析

​随着全球化进程的不断推进&#xff0c;越来越多的初创品牌意识到海外市场的巨大潜力&#xff0c;并希望能够将自己的品牌推广到更广阔的国际舞台上。然而&#xff0c;对于初创品牌来说&#xff0c;进军海外市场并开展品牌营销是一项具有挑战性的任务。本文Nox聚星将介绍一些初…

百变探影器 - 是一款很多人都在用的剪辑软件

有没有一款剪辑软件&#xff0c;它不仅颜值高&#xff0c;不用花时间学习就会剪&#xff0c;还自带丰富转场、片头片尾、字幕模板呢&#xff1f;那不得不说的就是一款超级能打的国产剪辑软件—百变探影器软件。 Pr这些比较专业的剪辑软件&#xff0c;基本都需要拥有一定的剪辑…

【实验八】多线程

1、完成书上268页习题第7题和实验题第1、2题 &#xff08;1&#xff09;第7题 import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*;public class RollWords extends JFrame{ static RollWords.MyThread thre…

西门子S7-200西门子200plc以太网配置向导

方案摘要&#xff1a; 西门子 S7200 系列 PLC通过MatrikonOPC实现以太网连接&#xff0c;捷米特ETH-S7200-JM01以太网模块为 PLC200转换出以太网通讯接口。 功能简介 MatrikonOPC是世界上最大的OPC开发商和供应商&#xff0c;我们的产品涵盖了OPC服务器、客户端、应用程序、O…

为D1定义一个f()函数,重做练习1-3,并解释其结果

运行代码&#xff1a; //为D1定义一个f()函数&#xff0c;重做练习1-3,并解释其结果 #include"std_lib_facilities.h" //---------------------------------------------------------------------- //定义B1类。 class B1 { public:virtual void vf() { cout<<…

第四章 数学知识(二)——欧拉函数,快速幂,扩展欧与中国剩余定理

文章目录 欧拉函数线性筛求欧拉函数欧拉定理 快速幂逆元 扩展欧几里得中国剩余定理扩展中国剩余定理 欧拉函数练习题873. 欧拉函数874. 筛法求欧拉函数 快速幂练习题875. 快速幂876. 快速幂求逆元 扩展欧练习题877. 扩展欧几里得算法878. 线性同余方程 中国剩余定理练习题204. …

Linux进程信号(一)

信号产生 1.信号基础知识2.初步认识信号3.signal函数4.技术应用角度的信号5.调用系统函数向进程发信号6.由软件条件产生的信号7.硬件异常产生信号8.core &#x1f31f;&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f…