小米科技|动态调整web系统主题? 看这一篇就够了( 二 )


这样我们的那些变量默认值字符串就添加进了 :root 根元素中:
/* result */ :root{   --color-canvas-default-transparent: 34 39 46;   --color-marketing-icon-primary: 108 182 255;   --color-marketing-icon-secondary: 49 109 202;   --color-diff-blob-addition-num-text: 173 186 199;   --color-diff-blob-addition-fg: 173 186 199;   --color-diff-blob-addition-num-bg: 87 171 90;   --color-diff-blob-addition-line-bg: 70 149 74;   --color-diff-blob-addition-word-bg: 70 149 74;   --color-diff-blob-deletion-num-text: 173 186 199;   ... 


这里注意全局变量中存储的是字符串 , 并不是颜色变量本身 。
但是有了这些 , 没有对应的 class 和 scss 变量 , 我们还是很不好使用这些变量的 , 那么怎么进行工程化来提升我们的开发效率呢?接下来重点来了 。
2. scss 与 js通信 , 动态生成 scss 变量与原子化 class
首先编写 export.scss 用于暴露对象给 js 使用:
// export.scss @use './constants.scss' as C; @use './util.scss' as Util; :export {   @each $var $color in C.$root-vars {     #{$var: Util.getRgbaString($color);    
然后利用 webpack sass-loader 中 js 和 scss 的通信方法 , 就可以生成:
  • variables.scss (全局scss变量文件)
  • extendColors.cjs (tailwindcss colors 配置文件)
// generator.js 生成器 import variables from '@/assets/scss/export.scss' // 简易的去除前缀 removeColorPrefix(str) {   return str.substring(8)  // 此时的 variables 是一个 object // 那么scss全局变量的模板生成为: scssFilterShadow(str) {   return `rgb(var(${str))`  // scss模板为 ${{ removeColorPrefix(k) :{{ scssFilterShadow(k) ; // 此时 原子化的 `tailwindcss colors` 文件生成为: jsFilterShadow(str) {   return `withOpacityValue('${str')`  // tailwindcss模板为 '{{ removeColorPrefix(k) ':{{ jsFilterShadow(k) 
通过这种方式 , 我们把生成的结果写入 variables.scss 和 extendColors.cjs 文件内 , 从而便捷把第一步中维护的如此之多的 css变量 , 全部快速方便的转化为同等的 scss变量 和 tailwindcss 配置
3. 全局scss文件变量注入
生成 variables.scss后 , 我们可以配置一下 sass-loader 来让其中的变量无需显式引入 , 即可在全局生效:
// sass-loader {   additionalData: '@use \"@/assets/scss/variables.scss\"  *;' 
这样我们就可以在任意的 vue <style> 或者 .scss 文件内使用到所有 variables.scss 中声明的变量了 。
4. 原子化的 class 生成
生成 extendColors.cjs 后 , 我们在里面添加:
function withOpacityValue(variable) {   return ({ opacityValue ) => {     if (opacityValue === undefined) {       return `rgb(var(${variable))`          return `rgb(var(${variable) / ${opacityValue)`