使用SCSS实现切换主题色

2,884 阅读1分钟

直接上代码

/** 设置主题 */
changeTheme(data) {
    // 给根节点设置data-theme属性,切换主题色就是修改data-theme的值,这里data=dark/light
    window.document.documentElement.setAttribute('data-theme', data); 
},
  1. 创建themes.scss文件,定义一个map类型的变量themes,相当于JS中的对象,不过是用圆括号包裹。themes,相当于JS中的对象,不过是用圆括号包裹。 themes中定义不同的主题名称,这里是light,dark。再定义主题对应的颜色。注意不同主题色的键值对的键名要相同。
$themes: (
  light: (
    bgColor1: #ffffff,
    bgColor2: #333333,
    fontColor1: rgba(0000.5),
    fontColor2: #333333,
    border1: 1px solid #e5e5e5,
    border2: 1px solid #ffffff,
    opacity1: 0.7
  ),
  dark: (
    bgColor1: #1a1a1a,
    bgColor2: #000000,
    fontColor1: rgba(2552552550.8),
    fontColor2: #999999,
    border1: none,
    border2: 1px solid #000000,
    opacity1: 1
  )
);
  1. 创建handle.scss文件,导入$themes文件。 定义混入器themeify,用来获取data-theme的值。

@each遍历themes的键值对,themes的键值对,theme-name对应light,dark。$theme-map对应light,dark的值。这两个变量名随意设定。

@content用来在引用themeify时导入内容。如果data-theme=light,就会编译成[data-theme=light] .class {}

再定义一个函数themed,根据data-theme和传过来的$key去theme.scss里获取相应的颜色。

再根据需要的css属性定义不同的混入器。

@import './themes.scss';

@mixin themeify {
  @each $theme-name, $theme-map in $themes {
    $theme-map: $theme-map !global;      // $theme-map为全局变量
    [data-theme='#{$theme-name}'] & {    // 判断html的data-theme的属性值  #{}是sass的插值表达式
      @content;                          // & 嵌套里的父容器标识   @content是混合器插槽,像vue的slot
    }
  }
}
@function themed($key) {
  @return map-get($theme-map, $key);  // map-get($map,$key) 函数的作用是根据 $key,返回 $key 在 $map 中对应的值。比如themed(bgColor1)返回 #ffffff 或 #1a1a1a。
}

// 获取背景颜色
@mixin background_color($color) {
  @include themeify {
    background-color: themed($color);
  }
}
// 获取字体颜色
@mixin font_color($color) {
  @include themeify {
    color: themed($color);
  }
}
@mixin border_color($color) {
  @include themeify {
    border-color: themed($color);
  }
}
@mixin opacity($data) {
  @include themeify {
    opacity: themed($data);
  }
}
  1. 在代码中使用,导入handle.scss
<style lang="scss" scoped>
@import "src/common/scss/handle.scss"
  .change-btn {                                
    @include font_color('fontColor1');         
    @include background_color('bgColor1');     
    @include border('border1');                
  }
</style>

最终编译成

微信图片_20210624202244.png