文章目錄
- 1. 樣式目錄文件架構
- 2. SCSS 樣式變量
- 2.1 設置顏色 SCSS 變量
- 2.2 設置多種類型主題
- 2.3 生成全局類型主題 SCSS 變量
- 2.4 分組生成 SCSS 變量
1. 樣式目錄文件架構
packages/theme-chalk 目錄結構:
├── packages
│ ├── theme-chalk
│ │ ├── src
│ │ │ ├── common
│ │ │ │ └── var.scss // SCSS變量配置文件
│ │ │ ├── mixins
│ │ │ │ ├── _var.scss // CSS變量相關的SCSS自定義函數
│ │ │ │ ├── config.scss // 配置文件
│ │ │ │ ├── function.scss // 全局的SCSS自定義函數
│ │ │ │ └── mixins.scss // BEM相關函數
│ │ │ ├── base.scss // 基礎必須要引用的文件
│ │ │ ├── button.scss // 按需導入組件的 CSS 文件
│ │ │ ├── index.scss // 全量導入組件庫的 CSS 入口文件
│ │ │ ├── var.scss // CSS 變量配置文件
│ │ │ ├── reset.scss // 默認樣式重置配置文件
通過 theme-chalk/src/common/var.scss 中的 SCSS 變量配置在 theme-chalk/src/var.scss 中進行封裝生成全局的 CSS 變量,在這個過程中使用到的有關生成 CSS 變量的 SCSS 自定義函數則在 theme-chalk/src/mixins/_var.scss 文件中進行設置。
因為要實現按需導入組件,所以各個組件單獨一個 CSS 文件。例如 Button 組件的 CSS 文件對應就是 button.scss 文件。在編寫組件 CSS 樣式中需要使用到的 BEM 的 SCSS 自定義函數則在 theme-chalk/src/mixins/mixins.scss 中,其他的 SCSS 自定義函數則在 theme-chalk/src/mixins/function.scss 中。
base.scss 文件則是引用那些必須的文件,比如 var.scss 文件是必須,這類文件則放在 base.scss 文件中。在全量導入組件庫的 CSS 入口文件 index.scss 中最先引入的便是 base.scss 文件。將來組件的自己的按需導入的 CSS 文件,例如 packages/components/button/style/index.ts 也就是 Button 組件的按需導入的 CSS 文件,其中也是需要最先導入 base.scss 文件,再進行導入 button.scss 文件。
2. SCSS 樣式變量
2.1 設置顏色 SCSS 變量
// packages/theme-chalk/src/common/var.scss@use 'sass:map';
// 默認顏色映射,使用 deep-merge 來允許用戶自定義顏色映射覆蓋默認值
$colors: () !default;
$colors: map.deep-merge((// 白色和黑色作為基本顏色選項'white': #ffffff,'black': #000000,// 為每種主題類型定義一個基礎顏色'primary': ('base': #409eff,),'success': ('base': #67c23a,),'warning': ('base': #e6a23c,),'error': ('base': #f56c6c,),'info': ('base': #909399,),),$colors
);// 主色調
$color-white: map.get($colors, 'white') !default; // 白色
$color-black: map.get($colors, 'black') !default; // 黑色// 應用場景顏色
$color-primary: map.get($colors, 'primary', 'base') !default; // 主要顏色,默認使用'base'色調
$color-success: map.get($colors, 'success', 'base') !default; // 成功狀態顏色,默認使用'base'色調
$color-warning: map.get($colors, 'warning', 'base') !default; // 警告狀態顏色,默認使用'base'色調
$color-error: map.get($colors, 'error', 'base') !default; // 錯誤狀態顏色,默認使用'base'色調
$color-info: map.get($colors, 'info', 'base') !default; // 信息狀態顏色,默認使用'base'色調
先設置一個總的 $colors 變量,然后再單獨設置每一個具體類型的變量,變量值是繼承 $colors 變量,這樣將來只要修改 $colors 中的變量值,后續每個繼承 $colors 變量的 SCSS 變量都將發生改變。
2.2 設置多種類型主題
- 定義主題類型
// packages/theme-chalk/src/common/var.scss// 定義可用的主題類型
$types: primary, success, warning, error, info;
- 擴展顏色變量
// packages/theme-chalk/src/common/var.scss
@use 'sass:math';/*** 該@mixin用于根據指定的顏色類型、級別和混合模式,創建一個新顏色等級并將其添加到全局顏色地圖中。* @param $type {string} - 顏色的類型(例如:primary, success等)。* @param $number {int} - 顏色的級別,用于計算顏色的混合程度。* @param $mode {string} - 混合模式,默認為'light'。可用于指定顏色是明度混合還是飽和度混合等。* @param $mix-color {color} - 用于混合的顏色,默認為白色($color-white)。*/
@mixin set-color-mix-level($type,$number,$mode: 'light',$mix-color: $color-white
) {// 深度合并顏色地圖,添加新的顏色等級$colors: map.deep-merge(($type: ('#{$mode}-#{$number}':mix($mix-color,map.get($colors, $type, 'base'),math.percentage(math.div($number, 10))),),),$colors) !global; // 將局部變量轉換為全局變量,確保新的顏色等級可以在整個項目中使用
}@each $type in $types {@for $i from 1 through 9 {@include set-color-mix-level($type, $i, 'light', $color-white);}
}
執行上述代碼就等于往各類型中添加新的變量顏色,效果如下:
$colors:('primary': ('base': #409eff,'light-1': 通過mix生成的新顏色,'light-2': 通過mix生成的新顏色,'light-3': 通過mix生成的新顏色,// ...),'success': ('base': #67c23a,'light-1': 通過mix生成的新顏色,'light-2': 通過mix生成的新顏色,'light-3': 通過mix生成的新顏色,// ...),'warning': ('base': #e6a23c,'light-1': 通過mix生成的新顏色,'light-2': 通過mix生成的新顏色,'light-3': 通過mix生成的新顏色,// ...),// ...)
2.3 生成全局類型主題 SCSS 變量
// src/var.scss@use 'common/var' as *;
@use 'mixins/var' as *;// 公共變量
:root {@include set-css-var-value('color-white', $color-white);@include set-css-var-value('color-black', $color-black);
}// 亮色模式
:root {color-scheme: light;// --v-color-#{$type}// --v-color-#{$type}-light-{$i}@each $type in $types {@include set-css-color-type($colors, $type);}
}
// src/mixins/_var.scss@use 'sass:map';
@use 'function' as *;// @include set-css-var-value(('color', 'primary'), red);
// --v-color-primary: red;
@mixin set-css-var-value($name, $value) {#{joinVarName($name)}: #{$value};
}@mixin set-css-var-value($name, $value) {#{joinVarName($name)}: #{$value};
}// @include set-css-var-type('color', 'primary', $map);
// --v-color-primary: #{map.get($map, 'primary')};
@mixin set-css-var-type($name, $type, $variables) {#{getCssVarName($name, $type)}: #{map.get($variables, $type)};
}@mixin set-css-color-type($colors, $type) {@include set-css-var-value(('color', $type), map.get($colors, $type, 'base'));@each $i in (3, 5, 7, 8, 9) {@include set-css-var-value(('color', $type, 'light', $i),map.get($colors, $type, 'light-#{$i}'));}@include set-css-var-value(('color', $type, 'dark-2'),map.get($colors, $type, 'dark-2'));
}
// src/mixins/function.scss/*** 函數用于將給定列表中的項目連接成一個變量名。* @param $list - 一個包含要連接的字符串的列表。* @return $name - 連接后的變量名,以"--"和配置中的命名空間開頭,每個列表項之間用"-"連接。*/
@function joinVarName($list) {// 初始化變量名,以"--"和配置中的命名空間開頭$name: '--' + config.$namespace;// 遍歷列表中的每個項目@each $item in $list {// 如果項目不為空,則將其添加到變量名中@if $item != '' {$name: $name + '-' + $item;}}// 返回連接后的變量名@return $name;
}// getCssVarName('button', 'text-color') => '--v-button-text-color'
@function getCssVarName($args...) {@return joinVarName($args);
}
// src/base.scss@use 'var.scss';
// src/index.scss@use './base.scss';@use './button.scss';
運行play項目,可以在控制臺看到
2.4 分組生成 SCSS 變量
以分組的模式生成不同分組的 CSS 變量
// src/common/var.scss// 文本顏色
$text-color: () !default;
$text-color: map.merge(('primary': #303133,'regular': #606266,'secondary': #909399,'placeholder': #a8abb2,'disabled': #c0c4cc,),$text-color
);// 邊框顏色
$border-color: () !default;
$border-color: map.merge(('': #dcdfe6,'light': #e4e7ed,'lighter': #ebeef5,'extra-light': #f2f6fc,'dark': #d4d7de,'darker': #cdd0d6,),$border-color
);// 填充顏色
$fill-color: () !default;
$fill-color: map.merge(('': #f0f2f5,'light': #f5f7fa,'lighter': #fafafa,'extra-light': #fafcff,'dark': #ebedf0,'darker': #e6e8eb,'blank': #ffffff,),$fill-color
);// 背景顏色
$bg-color: () !default;
$bg-color: map.merge(('': #ffffff,'page': #f2f3f5,'overlay': #ffffff,),$bg-color
);
// src/var.scss
:root {color-scheme: light;// --v-text-color-#{$type}@include set-component-css-var('text-color', $text-color);// --v-border-color-#{$type}@include set-component-css-var('border-color', $border-color);// Fill --v-fill-color-#{$type}@include set-component-css-var('fill-color', $fill-color);// Background --v-bg-color-#{$type}@include set-component-css-var('bg-color', $bg-color);
}
// src/mixins/_var.scss/*** 設置分組的CSS變量* @param $name - 分組名稱,用于生成CSS變量名。* @param $variables - 一個映射表,包含要設置的變量名和其值。* 該mixin遍歷$variables映射表,為每個鍵值對生成相應的CSS變量。如果鍵是"default",* 則設置基礎的CSS變量;否則,設置帶有特定后綴的CSS變量。*/
@mixin set-component-css-var($name, $variables) {@each $attribute, $value in $variables {// 根據$attribute的值決定是設置基本變量還是特定屬性的變量@if $attribute == 'default' {#{getCssVarName($name)}: #{$value}; // 設置默認的CSS變量} @else {#{getCssVarName($name, $attribute)}: #{$value}; // 設置具有特定后綴的CSS變量}}
}
運行play項目,可以在控制臺看到