1.创建themes.scss文件,定义一个map类型的变量$themes,相当于JS中的对象,不过是用圆括号包裹。
$themes中定义不同的主题名称,这里是light,dark。再定义主题对应的颜色。注意不同主题色的键值对的键名要相同。
// themes.scss
$themes: (
light: (
bgColor1: #ffffff,
bgColor2: #333333,
fontColor1: rgba(0, 0, 0, 0.5),
fontColor2: #333333,
),
dark: (
bgColor1: #1a1a1a,
bgColor2: #000000,
fontColor1: rgba(255, 255, 255, 0.8),
)
);
-
创建handle.scss文件,导入$themes文件。
-
定义混入器themeify,用来获取data-theme的值。
@each遍历 t h e m e s 的键值对, 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属性定义不同的混入器。
// handle.scss
@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);
}
}
在代码中使用,导入handle.scss
// header.vue
/** 设置主题 */
//data值为light,dark
changeTheme(data) {
window.document.documentElement.setAttribute('data-theme', data); // 给根节点设置data-theme属性,切换主题色就是修改data-theme的值
},
<style lang="scss" scoped>
@import "src/common/scss/handle.scss
.change-btn {
@include font_color('fontColor1');
@include background_color('bgColor1');
@include border('border1');
}
</style>
编译成