前言
- BEM 是
css
常用的命名规范 - BEM :
block(块)
、element(元素)
、modify(修饰符)
- 以
namespace-block__element
、namespace-block---modify
格式为例(namespace 一般是 ui 库的前缀,如 element-ui 的 el 前缀) scss
的使用请参考 scss中文网
一、创建全局 scss文件
在 src 下新建文件 bem.scss,用到 scss 的一些知识:
父子选择器
直接嵌套使用
变量声明 $
插值
使用:#{变量名}
@mixin
定义混入,@include
使用混入@at-root
跳出嵌套
$namespace: "xm" !default; // 命名空间
$block-sel: "-" !default; // block 用 - 连接
$element-sel: "__" !default; // element 用 __ 连接
$modify-sel: "--" !default; // modify 用 -- 连接。 如 xm-page__button--primary
// 生成 block 的规范类,如 .xm-block{}
@mixin b($block) {
$B: #{$namespace + $block-sel + $block};
.#{$B} {
// 这里类似于 插槽的功能,把对应的样式填进来
@content;
}
}
// 生成 element 的规范类,如 .xm-block__inner{}
@mixin e($el) {
// 首先,要先获取父级的类名,使用 &,对应的就是 .xm-block
$selector: &;
// 拼接出来是 .xm-block__inner{}
// 但编译出来的 会是 .xm-block .xm-block__inner{}
// #{$selector + $element-sel + $el} {
// @content;
// }
// 如果不想要父级名称,只需要 .xm-block__inner{},则使用 @at-root
@at-root {
#{$selector + $element-sel + $el} {
@content;
}
}
}
// 生成 modify 的规范类,如 .xm-block__inner--primary{}
@mixin m($mod) {
$selector: &;
@at-root {
#{$selector + $modify-sel + $mod} {
@content;
}
}
}
二、配置为全局使用
注意,这里直接在 App.vue 的 style 中引入是会报错的,必须在 vite.config.ts
中配置
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
// 配置 css
css: {
// 配置 预处理器
preprocessorOptions: {
// 配置 scss
scss: {
// 配置 附加数据
additionalData: `@import './src/bem.scss';`,
},
},
},
});
三、组件中使用
- 普通嵌套,编译后会
加上父级前缀
- 注意
&
的用法,直接使用不会多父级前缀,但使用 bem.scss 这里会多一层,所以 bem.scss中使用 @at-root 跳出了嵌套
<div class="blue">
哈哈哈
<div class="blue-name">笑笑</div>
</div>
<div class="xm-test">
B
<div class="xm-test__inner">E</div>
<div class="xm-test--success">M</div>
</div>
</div>
<style lang="scss" scoped>
// blue-name 这样写编译出来的 是 .blue .blue-name {}
.blue {
font-size: 30px;
.blue-name {
font-size: 40px;
}
}
// blue-name 这样写编译出来的是 .blue-name {}
.blue {
font-size: 30px;
&-name {
font-size: 40px;
}
}
// 书写时必须保持对应的嵌套关系,否则无效
@include b(test) {
color: red;
font-size: 40px;
@include e(inner) {
color: blue;
font-size: 30px;
}
@include m(success) {
color: green;
font-size: 16px;
}
}
</style>