element-plus 中的 sass (1)

1,201 阅读2分钟

学习一下大型项目中sass 的那些高阶用法,主要学习element-plus中的样式处理

在文件packages/theme-chalk/src 文件下是组件样式


首先看var.scss

var.scss

@use 'sass:map';
@use 'common/var' as *;
@use 'mixins/var' as *;
@use 'mixins/mixins' as *;

:root {
    @include set-css-var-value('color-white', $color-white);
    
    @each $type in (primary, success, warning, danger, error, info) {
        @include set-css-color-rgb($type);
  }
  
   @include set-component-css-var('font-size', $font-size);
}

// for light
:root {
    color-scheme: light;
    @include set-css-var-value('color-white', $color-white);
     @include set-css-var-value( 'border',
        getCssVar('border-width') getCssVar('border-style')
      getCssVar('border-color')
  );
}

var.scss文件中,顶部使用use 引入其他文件 ,可以使用其他文件的方法

@use规则从其他Sass样式表加载mixins函数变量,并将多个样式表css组合在一起

// src/_corners.scss
$radius: 3px;

@mixin rounded {
 border-radius: $radius;
}


// style.scss 中使用
// 默认情况下,模块的名称空间只是其URL的最后一个组成部分,而没有文件扩展名
@use "src/corners";

.button {
  // 命名空间
  @include corners.rounded;
  padding: 5px + corners.$radius;
}
// @use "<url>" as * 没有命名空间,直接使用
  1. common/varpackages/theme-chalk/src/common/var
  2. mixins/varpackages/theme-chalk/src/mixins/_var(注意有下划线,模块加载而不是编译)
  3. mixins/mixinspackages/theme-chalk/src/mixins/mixins

主要介绍三个函数

  1. set-css-var-value
  2. set-css-color-rgb
  3. set-component-css-var

set-css-var-value

packages/theme-chalk/src/mixins/_var

@use 'sass:map';

@use 'config';
@use 'function' as *;
@use '../common/var' as *;

@mixin set-css-var-value($name, $value) {
  #{joinVarName($name)}: #{$value};
}

同样引入了其他文件 ,使用函数 joinVarName

joinVarName

@use 'config';
// joinVarName(('button', 'text-color')) => '--el-button-text-color'
@function joinVarName($list) {
 // $namespace: 'el' !default; 在config 文件中
  $name: '--' + config.$namespace;
  @each $item in $list {
    @if $item != '' {
      $name: $name + '-' + $item;
    }
  }
  @return $name;
}

在函数joinVarName 使用变量config.$namespace 作为前缀词
遍历传入的参数$list, 只要$list中的$item 不是空字符串,就要拼接
joinVarName(('button', 'text-color'))传入两项,拼接结果是--el-button-text-color

image.png

@each $type

@each $type in (primary, success, warning, danger, error, info) {
    @include set-css-color-rgb($type);
  }

遍历 primary, success,...几个 字符串,传入set-css-color-rgb

set-css-color-rgb

在文件 packages/theme-chalk/src/mixins/_var

传入 一个type

@mixin set-css-color-rgb($type) {
  $color: map.get($colors, $type, 'base');
  @include set-css-var-value(
    ('color', $type, 'rgb'),
    #{red($color),
    green($color),
    blue($color)
    }
  );
}

使用 map.get 获取$color, 然后分别传入red,green,bluesass自带函数中获取对应的 16进制

map.get

在文件 packages/theme-chalk/src/common/var

$colors: () !default;
$colors: map.deep-merge(
  (
    'white': #ffffff,
    'black': #000000,
    'primary': (
      'base': #409eff,
    ),
    'success': (
      'base': #67c23a,
    ),
    'warning': (
      'base': #e6a23c,
    ),
    'danger': (
      'base': #f56c6c,
    ),
    'error': (
      'base': #f56c6c,
    ),
    'info': (
      'base': #909399,
    ),
  ),
  $colors
);

使用了map.deep-merge可以对对象进行合并
例如:


$light-weights: ("lightest": 100, "light": 300);
$heavy-weights: ("medium": 500, "bold": 700);

map.merge($light-weights, $heavy-weights);

// (
//   "lightest": 100,
//   "light": 300,
//   "medium": 500,
//   "bold": 700
// )

danger 字符串为 例子

image.png 渲染结果
image.png

set-component-css-var

在文件 packages/theme-chalk/src/mixins/_var
使用 @include set-component-css-var('font-size', $font-size);

$font-size

  $font-size: () !default;
  $font-size: map.merge(
   (
    'extra-large': 20px,
    'large': 18px,
    'medium': 16px,
    'base': 14px,
    'small': 13px,
    'extra-small': 12px,
  ),
  $font-size
);

set-component-css-var

// @include set-component-css-var('font-size', $font-size);

@mixin set-component-css-var($name, $variables) {
  @each $attribute, $value in $variables {
    @if $attribute == 'default' {
      #{getCssVarName($name)}: #{$value};
    } @else {
      #{getCssVarName($name, $attribute)}: #{$value};
    }
  }
}

getCssVarName

getCssVarName 在 文件 packages/theme-chalk/src/mixins/function

@function getCssVarName($args...) {
  @return joinVarName($args);
}

image.png

渲染结果

image.png


总结

 @function joinVarName($list) {
  $name:'-' + 'el';
  @each $item in $list {
    @if $item != '' {
      $name: $name + '-' + $item;
    }
  }
  @return $name;
}
  1. set-css-var-value set-css-var-value('color-white', $color-white)
    内部通过joinVarName 拼接字符作为key 值, value 为$color-white
@mixin set-css-var-value($name, $value) {
  #{joinVarName($name)}: #{$value};
}
  1. set-css-color-rgb 还是利用set-css-var-value,不过这次joinVarName接受了一个$list
@mixin set-css-color-rgb($type) {
 // 获取对应的 $color 值
  $color: map.get($colors, $type, 'base');
  @include set-css-var-value(
   // 这三个拼接,set-css-var-value 中的 $name 是一个list 类型
    ('color', $type, 'rgb'),
    #{red($color),
    green($color),
    blue($color)}
  );
}
  1. set-component-css-var

@mixin set-component-css-var($name, $variables) {
    // $font-size 是 { 'extra-large': 20px,  'large': 18px } 
  @each $attribute, $value in $variables {
      // #{getCssVarName($name, $attribute)}: #{$value};
      // @function getCssVarName($args...) {
      //   @return joinVarName($args);
      // } 
      // 可以直接写成 这样,但是必须要加 ()作为一个整体
      #{joinVarName(($name, $attribute))}: #{$value};
  }
}

element-plus不仅有出色的ts,tsx,vue组件,他的css也值得学习,这次作为学习element-plus开篇,浅浅的记录一下
time:2022/12/13