preface

This is mainly a study note on the unified encapsulation of styles for elementUI components while reading the source code. You can learn how to apply and encapsulate SCSS in a large project.

The directory structure

Element styles are stored in Element’s Packages/Theme-Chalk directory structure as follows:

│ alert. SCSS // Component style │ aside. SCSS │ avatar. SCSS │ backtop Breadcrumb - item. SCSS │ breadcrumb. SCSS │ button - group. SCSS │ button. The SCSS | / / omit part of the component style ├ ─ common/Shared style/component │ popup. The SCSS │ ├ ─ transition. SCSS // this is the style that defines the transition element in element │ ├─ Date-picker. SCSS │ ├─ Date-picker. SCSS │ ├─ Date-picker Date-range-picker. SCSS │ date-table. SCSS │ month-table. SCSS │ picker-panel Time-range-picker. SCSS │ time-spinner. SCSS │ year-table. SCSS │ ├─fonts // font file │ element.icons │ └ ─ mixins/config/SCSS multiplexing function. The SCSS / / style name global configuration function. The SCSS / / component style used to SCCSS function mixins. The SCSS utils. / / share mixins function SCSS / / Utility class function styles, such as disable user selection _button. SCSS // button base stylesCopy the code

Analysis of main documents

config.scss

The config. SCSS file defines the global configuration of element styles, such as style name prefixes, style name separators, and so on

$namespace: $el-button, $EL-select, $IS-disabled $namespace: $button, $EL-select, $IS-disabled'el';
$element-separator: '__';
$modifier-separator: The '-';
$state-prefix: 'is-';
Copy the code

mixins.scss

The mixins. SCSS file defines the basic mixins used by the Element component style, and the main mixinx ones are analyzed here

  1. @mixin B () mixed with el
@mixin b($block) {// If $block is a button $b: $namespace+'-'+$block! global; #{$B} {//.#{} {$B} {//. }} // @content 'is used in mixins. When a mixin is defined and @content // @include is set, the corresponding content can be passed into the mixinCopy the code
  1. @mixin e() mixed with __
@mixin e($element) {
  /** Assume that $element is disabled **/$E: $element ! global; $selector: &; // parent selector $currentSelector:""; // The selector to generate/** $B is the variable name of mixin B () mixin /* $B is used because e must be mixin B () mixin /* If e is mixin el-button, it will be generated .el-button__disabked **/
  @each $unit in $element {
    $currentSelector: #{$currentSelector + "." + $B + $element-separator + $unit + ","};
  }
  /** hitAllSpecialNestRule check if $elector contains --, is-, SCC (@at-root /* @at-root) is used to limit the output of one or more rules to the root of the document. Instead of being nested under its parent selector, style names prefixed with is-- etc. are generally removable in components, so the parent selector **/ is added to output at the root level of the document
  @if hitAllSpecialNestRule($selector) {
    @at-root {
      #{$selector} {
        #{$currentSelector} {
          @content; }}}}@else {
    @at-root {
      #{$currentSelector} {
        @content; }}}}Copy the code
  1. @mixin m() mixed with —
/** /* This method is basically the same as mixin e, except that hitAllSpecialNestRule is not checked because mixin -- generally the size style of the component, e.g El-radio --medium,el-radio--small, etc., the parent selector is usually el-radio, etc. /* so **/ is not needed
@mixin m($modifier) {
  $selector: &;
  $currentSelector: "";
  @each $unit in $modifier {
    $currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","};
  }

  @at-root {
    #{$currentSelector} {
      @content; }}}Copy the code
  1. @mixin w() mixin is
/** If $state is set to check /* then the compiler will compile to.el-radio.is-checked **/ at the document root level
@mixin when($state) {
  @at-root {
    &.#{$state-prefix + $state} {
      @content; }}}Copy the code

functon.scss

Function. SCSS defines the hitAllSpecialNestRule function method, which is used to determine whether a selector contains characters such as ‘is-‘, ‘–‘, ‘:’, etc. The main code is as follows:

@import "config";

/* BEM support Func -------------------------- */
@functionSelectorToString ($selector) {// Char $selector:inspect($selector);
  /** str-slice /* Truncates substrings from $string with $start-at and $end-at /*. If no end index is specified, the default truncation is the end of the string. /* The first and last characters are removed to avoid interference with --el, el: **/
  $selector: str-slice($selector, 2, -2);
  @return $selector;
}

@function containsModifier($selector) {
  $selector: selectorToString($selector);
    /** str-index($string, $substring) /* Returns an index indicating the starting position of $substring in $string. If not found, null is returned. /* $modifier-specarator -- **/
  @if str-index($selector, $modifier-separator) {
    @return true;
  } @else {
    @returnfalse; }}@function containWhenFlag($selector) {
  $selector: selectorToString($selector);
/** $state-prefix: 'is-'; * * /
  @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} // function hitAllSpecialNestRule($selector) {@return containsModifier($selector) or containWhenFlag($selector) or containPseudoClass($selector);
}
Copy the code