学习一下大型项目中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 引入其他文件 ,可以使用其他文件的方法
// 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 * 没有命名空间,直接使用
common/var在packages/theme-chalk/src/common/varmixins/var在packages/theme-chalk/src/mixins/_var(注意有下划线,模块加载而不是编译)mixins/mixins在packages/theme-chalk/src/mixins/mixins
主要介绍三个函数
- set-css-var-value
- set-css-color-rgb
- 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
@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 字符串为 例子
渲染结果
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);
}
渲染结果
总结
@function joinVarName($list) {
$name:'-' + 'el';
@each $item in $list {
@if $item != '' {
$name: $name + '-' + $item;
}
}
@return $name;
}
- 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};
}
- 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)}
);
}
- 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