Element Plus 源码分析
构建流程
参考资料:
https://juejin.cn/post/7076941611216666654?from=search-suggest
https://juejin.cn/post/7058190805768339470
1
| "build": "pnpm run -C internal/build start"
|
1
| "start": "gulp --require @esbuild-kit/cjs-loader -f gulpfile.ts"
|
样式篇
参考资料:
https://juejin.cn/post/7190370726677839932?from=search-suggest
https://juejin.cn/post/7101968262061113357
巧妙的封装 BEM
el 通过mixin 实现了 BEM (命名空间+模块 + 元素名 + 修饰器名) `namespace-block__element–modifier
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| $namespace: 'el'; // 命名空间 $element-separator: '__'; // 元素分隔符 $modifier-separator: '--'; // 修饰器分隔符 $state-prefix: 'is-' !default; @mixin b ($block) { // !global 将局部变量转为全局变量 $B: $namespace + '-' + $block !global; // 模板语法 .#{$B} { @content; } } @mixin e($element) { $E: $element !global; $selector: &; // & 表示父类选择器 $currentSelector: "";
@each $unit in $element { $currentSelector: #{$currentSelector + '.' + $B + $element-separator + $unit + ','} }
@if hitAllSpecialNestRule($selector) { // 如果 包含修饰器 状态 或者 伪类 则 // 返回 与父类同级 @at-root { #{$selector} { #{$currentSelector} { @content; } } } } @else { @at-root { #{$currentSelector} { @content; } } } }
@mixin m ($modifier) { $selector: &; $currentSelector: "";
@each $unit in $modifier { $currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","}; }
@at-root { #{$currentSelector} { @content; } } }
// 判断是否存在特殊嵌套 包含修饰器,包含状态 包含伪类 @function hitAllSpecialNestRule($selector) { @return containsModifier($selector) or containWhenFlag($selector) or containPseudoClass($selector); }
@function selectorToString($selector) { // inspect($value) 将列表转换成字符串 $selector: inspect($selector); // str-slice($string, $start-at, $end-at) 截取字符串 $selector: str-slice($selector, 2, -2); @return $selector; }
// 选择器是否包含修饰符 @function containsModifier($selector) { $selector: selectorToString($selector);
// 检查 选择器中 是否存在修饰器分隔符 @if str-index($selector, $modifier-separator) { @return true; } @else { @return false; } }
@function containWhenFlag($selector) { $selector: selectorToString($selector); // 是否包含状态前缀 @if str-index($selector, '.' + $state-prefix) { @return true } @else { @return false } }
@function containPseudoClass($selector) { $selector: selectorToString($selector);
// 是否包含伪类 @if str-index($selector, ':') { @return true } @else { @return false } } .test-bem{ color: purple; @include b(heade1r) { color:orange; } @include e(aa) { color:red; @include m (success) { color: green; } } } // 输出结果 .test-bem { color: purple; } .test-bem .el-heade1r { color: orange; } .el-heade1r__aa { color: red; } .el-heade1r__aa--success { color: green; }
|
CSS 变量封装