Skip to content

JSX的CSS样式

1. 行内样式

在jsx中的标签上使用style使用样式称为行内样式:

jsx
function MyComponent() {
    const myStyle = {backgroundColor:"#535bf2"}
    // 创建虚拟DOM
    return (
      <>
          <h2 style={myStyle}>我是函数定义的组件</h2>
          <h2 style={{width: '66px', height: '30px', backgroundColor:'red'}}>测试</h2>
      </>
    )
}

export default MyComponent

2. 全局样式

使用css文件编写样式,属于全局样式。比如新增test.css:

css
.box{
    position: relative;
    width: 120px;
    height: 60px;
    background-color: chocolate;
}
jsx
import './test.css'
function MyComponent() {
    return (
      <>
          <h2 className='box'>测试22</h2>
      </>
    )
}

export default MyComponent

如果在main.jsx中使用样式,此时无需再次导入:

jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './components/App.jsx'
import MyComponent from './components/MyComponent.jsx'

// 渲染虚拟DOM到页面
createRoot(document.getElementById('root')).render(
    <StrictMode>
        <App />
        <MyComponent/>
        <div className="box">测试3</div>
    </StrictMode>
)

此时浏览器效果:
Alt text

3. 局部样式

局部样式也是定义一个css文件,但是命名为xxx.module.css, 比如新建mycss.module.css:

css
.box2{
    width: 150px;
    height: 30px;
    background-color: greenyellow;
}

.box2-head{
    background-color: pink;
}

使用时就不再使用样式名,而是使用对象.xx的方式:

jsx
import myStyle from './mycss.module.css'
function MyComponent() {
    // 创建虚拟DOM
    return (
      <>
          <h2 className={myStyle.box2}>测试33</h2>
      </>
    )
}

export default MyComponent

如果此时在main.jsx中使用box2的样式是不生效的:
Alt text 查看html源码会发现,box2的样式动态在最终DOM上编译成_box2_qikgs_1的样式,这就是在其他地方直接使用box2不生效的原因,通过对象.xxx使用,必须需要引入这个xxx.module.css才能得到对象的引用,故而是局部样式。 Alt text

4. 样式支持驼峰

如果我们使用mycss.module.css的样式box2-head,

jsx
import myStyle from './mycss.module.css'
function MyComponent() {
    // 创建虚拟DOM
    return (
      <>
          <h2 className={myStyle.box2}>测试33</h2>
          <h2 className={myStyle.box2-head}>测试33</h2>
      </>
    )
}
export default MyComponent

会报错:
Alt text 解决办法1:使用对象['属性名']方式访问

jsx
<h2 className={myStyle['box2-head']}>测试33</h2>

解决办法2:使用驼峰方式,需要在vite中配置,vite提供给我们访问css的能力,修改vite.config.js:

js
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vite.dev/config/
export default defineConfig({
    plugins: [react()],
    server:{
        port: '9090',
    },
    css:{
       modules: {
           /*
           * dashes表示通过对象.xx方法访问
           * dashesOnly表示只支持对象.xx方法
           * camelCase表示驼峰的和对象.xxx方式都支持访问
           * camelCaseOnly表示只支持驼峰
           * */
           localsConvention: 'camelCase'
       }
    }
})

配置后发现页面已经生效: Alt text

5. 支持预处理Scss

预处理css的工具有sass、scss、less、stylus, 还有最近比较流行的Tailwind Css解决方案,本笔记简单使用scss(现在css功能越来越强了,预处理器使用的越来越少):

cmd
npm install -D sass

新增test.scss文件:

scss
$bg: red;

.newBox{
  background-color: $bg;
}

调整MyComponent.jsx文件内容:

jsx
import './demo.scss'
function MyComponent() {
    // 创建虚拟DOM
    return (
      <>
          <h2 className='newBox'>测试55</h2>
      </>
    )
}
export default MyComponent

局部样式类似也是创建xxx.module.scss文件。

6. 使用classnames工具

在jsx中使用对象.xxx就不能很多支持多个class样式,简单的解决方案是使用数组:

jsx
import myStyle from './mycss.module.css'
function MyComponent() {

  const myStyleArray = [myStyle.box2, myStyle.box3]
    return (
      <>
          <h2 className={myStyleArray.join(' ')}>测试88</h2>
      </>
    )
}
export default MyComponent

查看页面效果:
Alt text

6.1 安装classnames

但是使用样式数组还是不够灵活,毕竟大家开发习惯使用对象操作。所以有一个工具叫做classnames,使用对象的方式操作多个样式:

cmd
npm install -D classnames

调整main.jsx文件:

jsx
import myStyle from './mycss.module.css'
import classNames from 'classnames'
function MyComponent() {

  // const myStyleArray = [myStyle.box2, myStyle.box3]
  const myClass = classNames({
    box1: false, // 全局样式
    [myStyle.box2]: true, // 局部样式
    [myStyle.box3]: true,
  })
    return (
      <>
          <h2 className={myClass}>测试88</h2>
      </>
    )
}

export default MyComponent