引言
总的来说,我们的组件需要一个全局唯一的样式名,避免污染全局样式。
vue中有scoped可以给组件添加一个data-v-id的attribute,那在jsx中如何处理?
方式一
我们自己把组件中的样式命名的全局唯一。
方式二
postcss-modules是一个PostCSS插件,实现了css的模块化的概念,可以单独引用,每一个引用都是一个副本或着说是一个实例,自己带着唯一标识。
例如,你有以下CSS:
/* styles.css */
:global .page {
padding: 20px;
}
.title {
composes: title from "./mixins.css";
color: green;
}
.article {
font-size: 16px;
}
/* mixins.css */
.title {
color: black;
font-size: 40px;
}
.title:hover {
color: red;
}
经过改造后会变成这样:
._title_116zl_1 {
color: black;
font-size: 40px;
}
._title_116zl_1:hover {
color: red;
}
.page {
padding: 20px;
}
._title_xkpkl_5 {
color: green;
}
._article_xkpkl_10 {
font-size: 16px;
}
插件会为转换后的类提供一个JSON对象:
{
"title": "_title_xkpkl_5 _title_116zl_1",
"article": "_article_xkpkl_10"
}
在vite中使用:
CSS Modules
任何以 .module.css 为后缀名的 CSS 文件都被认为是一个 CSS modules 文件。导入这样的文件会返回一个相应的模块对象:
/* example.module.css */
.red {
color: red;
}
import classes from './example.module.css'
document.getElementById('foo').className = classes.red
CSS modules 行为可以通过 css.modules 选项 进行配置。
interface CSSModulesOptions {
scopeBehaviour?: 'global' | 'local'
globalModulePaths?: RegExp[]
generateScopedName?:
| string
| ((name: string, filename: string, css: string) => string)
hashPrefix?: string
/**
* 默认:null
*/
localsConvention?:
| 'camelCase'
| 'camelCaseOnly'
| 'dashes'
| 'dashesOnly'
| null
}
如果 css.modules.localsConvention
设置开启了 camelCase 格式变量名转换(例如 localsConvention: 'camelCaseOnly'
),你还可以使用按名导入。
// .apply-color -> applyColor
import {
applyColor } from './example.module.css'
document.getElementById('foo').className = applyColor
具体vite配置可以做个参考:
// https://vitejs.dev/config/
export default defineConfig({
css: {
modules: {
// 配置localsConvention则可以开启css模块功能
localsConvention: "camelCase",
hashPrefix: "data-v",
}
},
})
方式三
构建工具会将类名编译成一个哈希字符串,防止整个项目的类名重复。
- styled-components
- emotion
(未完待续)