使用实践

https://zhuanlan.zhihu.com/p/46073785

保证各个部分只有一级 BEM,原则上不会出现2层以上选择器嵌套
修饰器需要和对应的块或元素一起使用,避免单独使用。

  1. <ul class="l-grid">
  2. <li class="l-grid__item">
  3. <div class="c-card">
  4. <div class="c-card__header">
  5. </div>
  6. <div class="c-card__body">
  7. </div>
  8. </div>
  9. </li>
  10. </ul>
  1. <div class="mk-collapse">
  2. <div class="mk-collapse-item mk-collapse-item--expanded">
  3. <!--
  4. 对于折叠面板的header 层,我们可以划分一个单元格组件 mk-cell 组件 减少嵌套,当前层级可加mk-collapse-item__title class建立关联,后续的子元素归于mk-cell的层级,后续mk-cell也可独立在其他地方复用
  5. -->
  6. <div
  7. class="mk-cell mk-collapse-item__title "
  8. >
  9. <div class="mk-cell__title">
  10. <span>标题1</span>
  11. </div>
  12. <i class="mk-icon mk-cell__right-icon"></i>
  13. </div>
  14. <!--
  15. 对于分割线这类常规公告样式,我们可以直接用class ,独立出来,不必可以建立关联
  16. -->
  17. <div class="divider"></div>
  18. <div class="mk-collapse-item__wrapper">
  19. <div class="mk-collapse-item__content">Hello World</div>
  20. </div>
  21. </div>
  22. </div>

BEM函数

https://juejin.cn/post/6894265906596642829

  1. $namespace: 'el'; //前缀名
  2. $element-separator: '__'; //子元素连接符
  3. $modifier-separator: '--'; //块样式状态连接符
  4. $state-prefix: 'is-'; //特定状态列前缀
  1. /* BEM
  2. -------------------------- */
  3. @mixin b($block) {
  4. $B: $namespace+'-'+$block !global;
  5. .#{$B} {
  6. @content;
  7. }
  8. }
  9. @mixin e($element) {
  10. $E: $element !global;
  11. $selector: &;
  12. $currentSelector: "";
  13. @each $unit in $element {
  14. $currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","};
  15. }
  16. @if hitAllSpecialNestRule($selector) {
  17. @at-root {
  18. #{$selector} {
  19. #{$currentSelector} {
  20. @content;
  21. }
  22. }
  23. }
  24. } @else {
  25. @at-root {
  26. #{$currentSelector} {
  27. @content;
  28. }
  29. }
  30. }
  31. }
  32. @mixin m($modifier) {
  33. $selector: &;
  34. $currentSelector: "";
  35. @each $unit in $modifier {
  36. $currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","};
  37. }
  38. @at-root {
  39. #{$currentSelector} {
  40. @content;
  41. }
  42. }
  43. }

B

  1. @mixin b($block) {
  2. $B: $namespace+'-'+$block !global; //变量拼接形成对应格式的class;再使用!global将其提升为全局变量
  3. .#{$B} {
  4. @content; // 使用混合;大括号后定义的样式将都会解析到这里
  5. }
  6. }

E

  1. @mixin e($element) {
  2. $E: $element !global;
  3. $selector: &;
  4. $currentSelector: "";
  5. @each $unit in $element {
  6. $currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","};
  7. }
  8. //实际上@each内 其实就是变量拼接,通过__符连接父级选择器和传入的子元素,
  9. //而传入的值可以是一个,也可以是数组
  10. //判断父级选择器是否包含'--' 'is-' ':'
  11. @if hitAllSpecialNestRule($selector) {
  12. @at-root {
  13. #{$selector} {
  14. #{$currentSelector} {
  15. @content;
  16. }
  17. }
  18. }
  19. } @else {
  20. @at-root {
  21. #{$currentSelector} {
  22. @content;
  23. }
  24. }
  25. }
  26. }

例子:

  1. //执行混合;b方法的定义在这里就不重复写了
  2. @include b((card)) {
  3. border-radius: 4px;
  4. border: 1px solid #ebeef5;
  5. background-color: #fff;
  6. overflow: hidden;
  7. color: #303133;
  8. transition: 0.3s;
  9. @include e(footer) { //传入单个
  10. padding: 20px;
  11. }
  12. @include e((title, body)) { //传入数组
  13. padding: 20px;
  14. }
  15. }
  16. //编译后
  17. .mk-card .mk-card__footer { //传入单个编译结果
  18. content: "11";
  19. padding: 20px;
  20. }
  21. .mk-card .mk-card__title, //传入数组编译结果
  22. .mk-card .mk-card__body {
  23. content: "11";
  24. padding: 20px;
  25. }

例子:

  1. // 不含"--"、"is-"、 ":" 编译前 不包含,则通过@at-root跳出选择器嵌套
  2. .mk-card{
  3. $selector: &;
  4. @include e(footer) {
  5. //传入单个
  6. padding: 20px;
  7. }
  8. }
  9. // 编译后
  10. .mk-card__footer {
  11. padding: 20px;
  12. }
  13. // 含"--"、"is-"、 ":" 编译前 ;包含则嵌套于父级选择器下
  14. .mk-card:hover {
  15. $selector: &;
  16. @include e(footer) {
  17. //传入单个
  18. padding: 20px;
  19. }
  20. }
  21. //编译后
  22. .mk-card:hover .mk-card__footer {
  23. padding: 20px;
  24. }

M

  1. @mixin m($modifier) {
  2. $selector: &;
  3. $currentSelector: "";
  4. @each $unit in $modifier {
  5. $currentSelector: #{$currentSelector +
  6. & +
  7. $modifier-separator +
  8. $unit +
  9. ","};
  10. }
  11. @at-root {
  12. #{$currentSelector} {
  13. @content;
  14. }
  15. }
  16. }

例子:

  1. //编译前
  2. @include b(card) {
  3. border-radius: 4px;
  4. border: 1px solid #ebeef5;
  5. background-color: #fff;
  6. overflow: hidden;
  7. color: #303133;
  8. transition: 0.3s;
  9. @include e(footer) {
  10. //传入单个
  11. padding: 20px;
  12. }
  13. @include m(primary) {
  14. background: #409eff;
  15. }
  16. }
  17. //编译后
  18. .mk-card {
  19. border-radius: 4px;
  20. border: 1px solid #ebeef5;
  21. background-color: #fff;
  22. overflow: hidden;
  23. color: #303133;
  24. -webkit-transition: 0.3s;
  25. transition: 0.3s;
  26. }
  27. .mk-card__footer {
  28. padding: 20px;
  29. }
  30. .mk-card--primary {
  31. background: #409eff;
  32. }