# 一、React 中的 CSS

# 1、CSS 概述

  在当前前端组件化开发的时代,一个合适的 CSS 方案应该符合以下条件:

局部的、动态的、简洁的、支持度高的……

# 2、内联样式

  在 react 基础中就已经提到了 style={{}}语法

class Demo extends React.Component {
  constructor() {
    super()

    this.state = {
      imageSize: 200
    }
  }

  render() {
    const { imageSize } = this.state

    return (
      <div>
        {/* 直接使用 */}
        <p style={{ color: 'red', fontSize: '30px' }}>
          优于别人,并不高贵,真正的高贵应该是优于过去的自己。
        </p>

        {/* 使用变量 */}
        <img style={{ width: imageSize, height: imageSize }} />
      </div>
    )
  }
}

# 3、CSS Modules

  这种方式就不做过多介绍了,缺点是这些 css 默认是全局的。

import '@/css/common.css'

  为了解决 react 中的 css 全局问题,可以采用:

解决方案:CSS Modules🍗

  CSS Modules 提供各种插件 (opens new window),支持不同的构建工具。

CSS Modules 用法教程 (opens new window)

  常见的是 Webpack 的 css-loader 插件,因为它对 CSS Modules 的支持最好。

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,
        loader: 'css-loader',
        options: {
          modules: true // 开启 CSS Modules
        }
      }
    ]
  }
}

  当然,在 react 脚手架 (opens new window)中已经内置了 CSS Modules 的配置,我们只需要将样式文件名改为 .module.css、.module.less、.module.scss 等即可

提示

  react 脚手架中的 CSS Modules 方案中,css 类名是不能使用连接符的(例如:.home-nav

import common from './Common.module.css' // Import css modules stylesheet as styles

class Demo extends Component {
  render() {
    return <button className={common.error}>错误信息</button>
    // 会被解析为( 组件名_类名_hash值)
    // return <button className="Common_error_ax7yz">错误信息</button>
  }
}

# 二、CSS-in-JS ✨

# 1、简介

  “CSS-in-JS” 是指一种模式,其中 CSS 由 JavaScript 生成而不是在外部文件中定义。

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

目前比较流行的 CSS-in-JS 库有:styled-components (opens new window)emotion (opens new window)glamorous (opens new window)

# 2、styled-components 库

常见的 react 组件库 Material UI (opens new window) 就采用了 styled-components

js 拓展:🌹 标签模板字符串
const name = 'lencamo'
const age = 22

function foo(...args) {
  console.log(args) // [["my name is ", ", age is ", ""], "lencamo", 22]
}

foo`my name is ${name}, age is ${age}`

# 3、基本使用

  • 编写全局 css 变量

通过编写 variables 文件直接在 css 组件中引入数据

// variables.js
export const primaryColor = '#ff8800'
export const secondColor = '#ff77788'

export const smallSize = '12px'
export const middleSize = '14px'
export const largeSize = '18px'
  • 编写 css 组件
// style.js
import styled from 'styled-components'

import * as vars from '@/style/variables.js'

export const DemoWrapper = styled.div.attrs((props) => ({
  // 直接返回对象
  rColor: props.color || '#292c34' // 设置默认值
}))`
  .section {
    border: 1px solid red;

    .title {
      font-size: ${(props) => props.size}px;
      color: ${(props) => props.rColor};

      &:hover {
        background-color: purple;
      }
    }

    .content {
      font-size: ${vars.largeSize}px;
      color: ${vars.secondColor};
    }
  }

  .footer {
    border: 1px solid orange;
  }
`
  • 使用 css 组件

可以在使用 props 向 css 组件传递数据

import { DemoWrapper } from '@/css/style.js'

class Demo extends PureComponent {
  constructor() {
    super()

    this.state = {
      size: 30,
      color: 'green'
    }
  }

  render() {
    const { size, color } = this.state

    return (
      // DemoWrapper本身是一个组件
      <DemoWrapper size={size} color={color}>
        <div className="section">
          <h2 className="title">我是标题</h2>
          <p className="content">我是内容,哈哈哈</p>
        </div>

        <div className="footer">
          <p>免责声明</p>
          <p>版权声明</p>
        </div>
      </DemoWrapper>
    )
  }
}
其他高级特性
  • 支持样式的继承
  • 支持设置主题 ThemeProvider
  • ……

# 三、动态添加 class

# 知识回顾

  • vue 中添加 class
<!-- 数组、对象 -->
<div
  class="static"
  :class="['baseCss', activeClass, hasError ? 'text-danger' : '', { 'text-danger': hasError }]"
></div>
  • react 中添加 class
// 字符串、数组
<div
  className={`one two ${isShow ? 'avatar' : ''}`}
  className={['one', 'two', isShow ? 'avatar' : ''].join(' ')}
></div>

# 1、classnames 库

classnames 库 (opens new window)的使用和 vue 中的添加 class 方式类似

import classname from 'classnames'

class Demo extends React.PureComponent {
  render() {
    return <div className={classname(['one', 'two', { avatar: isShow }])}></div>
  }
}
更新于 : 8/7/2024, 2:16:31 PM