React第二十八章(css modules)

css modules

什么是 css modules

因为 React 没有Vue的Scoped,但是React又是SPA(单页面应用),所以需要一种方式来解决css的样式冲突问题,也就是把每个组件的样式做成单独的作用域,实现样式隔离,而css modules就是一种解决方案,但是我们需要借助一些工具来实现,比如webpackpostcsscss-loadervite等。

如何在Vite中使用css modules

css modules,可以配合各种css预处理去使用,例如lesssassstylus等。

sh 复制代码
npm install less -D # 安装less 任选其一
npm install sass -D # 安装sass 任选其一
npm install stylus -D # 安装stylus 任选其一

在Vite中css Modules 是开箱即用的,只需要把文件名设置为xxx.module.[css|less|sass|stylus],就可以使用css modules了。

  • src/components/Button/index.module.scss
css 复制代码
.button {
  color: red;
}
  • src/components/Button/index.tsx
tsx 复制代码
//使用方法,直接引入即可
import styles from './index.module.scss';

export default function Button() {
  return <button className={styles.button}>按钮</button>;
}
  • 编译结果, 可以看到button类名被编译成了button_pmkzx_6,这就是css modules的实现原理,通过在类名前添加一个唯一的哈希值,来实现样式隔离。
html 复制代码
<button class="button_pmkzx_6">按钮</button>

修改css modules 规则

  • 在vite.config.ts中配置css modules的规则
ts 复制代码
export default defineConfig({
  css: {
    modules: {
      localsConvention: 'dashes', // 修改css modules的类名规则 可以改成驼峰命名 或者 下划线命名
      generateScopedName: '[name]__[local]___[hash:base64:5]', // 修改css modules的类名规则
    },
  },
});

例子 例如设置为(localsConvention:camelCaseOnly)驼峰命名

  • src/components/Button/index.module.scss
scss 复制代码
.button-red {
  color: red;
}
  • src/components/Button/index.tsx

设置为驼峰之后,使用的时候需要使用驼峰命名,例如buttonRed,而不是button-red

tsx 复制代码
import styles from './index.module.scss';

export default function Button() {
  return <button className={styles.buttonRed}>按钮</button>;
}

例子 例如设置为(localsConvention:dashes)原始命名也就是-连接的命名

  • src/components/Button/index.module.scss
scss 复制代码
.button-red {
  color: red;
}
  • src/components/Button/index.tsx

设置为原始命名之后,使用的时候需要使用-连接的命名,例如button-red,而不是buttonRed

tsx 复制代码
import styles from './index.module.scss';

export default function Button() {
  return <button className={styles['button-red']}>按钮</button>;
}

如果想同时支持驼峰命名和-连接的命名,可以设置为localsConvention:camelCase,这样就可以同时支持驼峰命名和-连接的命名。

例子 修改css modules的类名规则

  • 在vite.config.ts中配置css modules的规则
ts 复制代码
export default defineConfig({
  css: {
    modules: {
        generateScopedName: '[local]_[hash:base64:5]' // 只保留类名和哈希值
        // 或者
        generateScopedName: '[hash:base64:8]' // 只使用哈希值
        // 或者
        generateScopedName: '[name]_[local]' // 只使用文件名和类名,没有哈希
        // 或者
        generateScopedName: '[local]--[hash:base64:4]' // 自定义分隔符
    },
  },
});

编译结果

html 复制代码
<button class="button_pmkzx_6">类名 + 哈希值</button>
<button class="pmkzx_6">哈希值</button>
<button class="index-module_button">文件名 + 类名</button>
<button class="button--pmkzx_6">类名 + 分隔符 + 哈希值</button>

维持类名

意思就是说在样式文件中的某些样式,不希望被编译成css modules,可以设置为global,例如:

scss 复制代码
.app{
    background: red;
    width: 200px;
    height: 200px;
    :global(.button){
        background: blue;
        width: 100px;
        height: 100px;
    }
}
tsx 复制代码
//在使用的时候,就可以直接使用原始的类名 button
import styles from './index.module.scss';
const App: React.FC = () => {
  return (
    <>
      <div className={styles.app}>
        <button className='button'>按钮</button>
      </div>
    </>
  );
}
相关推荐
NiceCloud喜云3 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
wordbaby3 小时前
React Native + RNOH:跨页面数据回传的最佳实践与避坑指南
前端·react native
丷丩3 小时前
MapLibre GL JS第22课:查看本地GeoJSON
前端·javascript·map·mapbox·maplibre gl js
Front思4 小时前
AI前端工程师需要具备能力+
前端·人工智能·ai
ZC跨境爬虫6 小时前
跟着 MDN 学CSS day_29:(掌握文本与字体样式的核心艺术)
前端·css·ui·html·tensorflow
李子琪。7 小时前
网络空间安全深度实战:CSRF 漏洞原理剖析与基于 Token 的纵深防御体系构建(全栈实验报告)
前端·安全·csrf
冰暮流星7 小时前
javascript之history对象介绍
前端·笔记
IT_陈寒7 小时前
Vite热更新失灵?你可能漏了这个配置
前端·人工智能·后端
丷丩7 小时前
MapLibre GL JS第19课:实时更新要素
前端·javascript·gis·map·mapbox·maplibre gl js
Mr.Daozhi7 小时前
RAG 进阶实战:跑通 Demo 后我连续翻了 6 次车,逐一修复才真正可用(含 Gradio Web 版)
前端·数据库·langchain·大模型·gradio·rag·科研工具