React 组件之样式

发布时间 2023-11-23 17:47:33作者: 背包の技术

无论你的梦想有多么高远,记住,一切皆有可能。

我们从前面的学习知道一个 React 组件不仅仅只包含 DOM 结构的,还应该样式和 Javascript 逻辑的。这里我们学习下如何构建 CSS 样式。

1. 逻辑表示

JSX 中使用大括号语法来包裹 JS 表达式(简单逻辑代码)。例如:

{ 1 + 1 }
{ 表达式/对象/变量/常量 }

2. 样式表示

React 推荐使用行内样式,因为 React 认为每一个组件都是一个独立的整体。具体样式参考文档:

https://www.runoob.com/css/css-tutorial.html

2.1 行内样式

想给虚拟 DOM 添加行内样式,需要使用表达式传入样式对象的方式实现,注意这里两个括号,第一个表示我们要在 JSX 里插入 JS 了,第二个是样式对象的括号:

import React, { Component } from "react"
import "./1-style.css"

class StyleApp extends Component {
  render() {
    return (
      <div>
        { 1+2 }
        {/* 行内样式 */}
        <div style={{backgroundColor: "red"}}>行内样式第一行数据</div>
        {/* 支持外部 CSS 文件 */}
        {/* class => className JSX 写法区别 JS 中关键字类 class */}
        <div className="active">外部CSS文件样式第二行数据:使用类选择器</div>
        {/* 使用 id 选择器 */}
        <div id="body">外部CSS文件样式第三行数据:使用id选择器</div>

        {/* for => htmlFor JSX 写法,同理 class 关键字 */}
        <label htmlFor="username">用户名:</label>
        <input type="text" id="username"/>
      </div>
    )
  }
}

export default StyleApp

2.2 外部 CSS 文件

语法格式和示例:

选择器 {
    属性名1: 属性值1,
    属性名2: 属性值2,
    ...
}
// CSS 文件
.active {
  background: orange;
}

#body {
  background: green;
}

CSS 导入原理:

webpack 将 CSS 文件转换成内部样式,加到 style 中,并插到插入到页面的 head 标签里。

import "./1-style.css"

3. 样式描述语言

3.1 CSS

CSS(Cascading Style Sheets,层叠样式表) 文件主要的用途是对网页中字体、颜色、背景、图像及其他各种样式元素的控制,使网页能够完全按照设计者的要求来显示。

3.2 Less

Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量、混合、函数等功能,让 CSS 更易维护、方便制作主题、扩充。

Less 文件最终需要编译成 CSS 文件进行样式的渲染,不过相对比与 CSS,Less 提供了一些额外的功能将有效提高我们开发的效率。

两者之间的区别:

变量:Less 允许单独定义一系列通用的变量,然后在需要的时候去进行调用, 方便更改,提高了代码的复用。示例:

@color: red;
.one{
  color:@color;
}
.two{
  color:@color;
}
.one{
  color:red;
}
.two{
  color:red;
}

嵌套:Less 可以使用一个选择器嵌套另外一个选择器,减少代码量。

运算:Less 中提供了加,减,乘,除操作;我们可以做属性值和颜色的运算,这样就可以实现属性值之间的复杂关系。示例:

@color: #333333;
.one{
  color:@color+#111111;
}

3.3 Sass

Sass 是一款强化 CSS 的辅助工具,它在 CSS 语法的基础上增加了变量 (variables)、嵌套 (nested rules)、混合 (mixins)、导入 (inline imports) 等高级功能,这些拓展令 CSS 更加强大与优雅。使用 Sass 以及 Sass 的样式库(如 Compass)有助于更好地组织管理样式文件,以及更高效地开发项目。

Less 和 Sass 如何选择:

https://so66.cn/102540.html

4. CSS Module 模块化

CSS 是层叠样式表(Cascading Style Sheets)的简称。用于渲染 HTML 式样的。 CSS 的读取是有自己的规则的,从右至左。当项目大点,类名相同时,难免会发生覆盖。从代码中看,明明已经设置了,但是为什么不起作用呢?为了解决这种问题,于是有了 CSS Modules 方案。

CSS 的模块化,这样的方式可以区分各个组件的样式,不会相互覆盖,而且还能定义伪类,React 脚手架当中内置了 CSS Modules 的配置,我们可以直接将 CSS 的文件定义为 xxx.module.css,在 xxx.module.css 文件中,还是按照以前的 CSS 编写方式编写,不同点在于 jsx 页面中定义 className,先引入该 css 文件,然后定义类名以对象的形式定义:

import style from './index.module.css'
return(<div className={style.title}>
    hello react
</div>)

这样定义的样式是一个不会重复的字符。这种定义样式的方式能够比较有效的解决样式重叠的问题,麻烦之处就是每次编写样式的时候需要通过对象的语法来定义,并且不支持动态的设置样式。

其次上面提到到 Less(Leaner Style Sheets 的缩写) 是一门向后兼容的 CSS 扩展语言。也可以解决上面提到的覆盖问题。

5. styles-components

它是通过 JavaScript 改变 CSS 编写方式的解决方案之一,从根本上解决常规 CSS 编写的一些弊端。通过 JavaScript 来为 CSS 赋能,我们能达到常规 CSS 所不好处理的逻辑复杂、函数复杂、函数方法、复用、避免干扰。样式书写将直接依附在 JSX 上面,HTML、CSS、JS 三者再次内聚。all in js 的思想。模块安装如下:

npm i styled-components

5.1 基础应用

style.label 会在原生组件基础上生成一个带样式的组件,原生组件本身的属性还是存在的,可以透传给组件内部。

import styled from 'styled-components'

export default class StyleComponent extends Component {
  render() {
    const StylesLebel = styles.label`
      background: red    
    `
    return (
      <div>
        <StylesLebel>StyleComponent</StylesLebel>
      </div>
    )
  }
}

5.2 透传 props

import styled from 'styled-components'

export default class StyleComponent extends Component {
 render() {
   const StylesLebel = styles.label`
     background: ${props=>props.bg}    
   `
   return (
     <div>
       <StylesLebel bg="red"></StylesLebel>
     </div>
   )
 }
}

5.3 样式化组件

import styled from 'styled-components'

export default class StyleComponent extends Component {
  render() {
    const StylesChild = styles(Child)`
      background: red  
    `
    return (
      <div>
        <StylesChild></StylesChild>
      </div>
    )
  }
}


function Child(props) {
  return <div className={props.className}>Child</div>
}

5.4 样式扩展

const MyButton = styled.button`
background: yellow;`

const BigButton = styled(MButton)`
height: 100px;
width: 100px;`