2021.03.29.vueChangeTheme


title:使用scss实现主题颜色动态切换功能
tags:[scss]

categories:随笔

通过给 html 根 标签设置一个 data-theme 属性,然后通过 js 来切换 data-theme 的属性值,接着 scss 根据 data-theme 的值来动态切换主题,从而实现需求.

定义

新建_theme.scss来保存预设的主题配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

//_theme.scss
//light 代表亮色主题,dark 代表暗色主体,不同主题的颜色,配置等必须一一对应.
//如果需要更多的主体,自行在 theme 中添加即可.

$themes: (
light: (
background-color: white,
title-font-color: white,
main-title-font-color: #1989fa,
form-item-label-color: #606266,
divider-color: #dcdfe6,
table-text-color: #606266,
notice-color: black,
msg-color: #606266,
table-border-color: #ebeef5,
hover-color: #f5f7fa,
),
dark: (
background-color: #1e2022,
title-font-color: #f1f5f9,
main-title-font-color: #5fa9ec,
form-item-label-color: #bec3c6,
divider-color: #444242,
table-text-color: #ecedec,
notice-color: white,
msg-color: white,
table-border-color: #3d3d3b,
hover-color: black,
),
);

新建_handle.scss来操作 _theme.scss中的变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// _handle.scss
@import "./_themes.scss";

//遍历主题map
@mixin themeify {
@each $theme-name, $theme-map in $themes {
//!global 把局部变量强升为全局变量
$theme-map: $theme-map !global;
//判断html的data-theme的属性值 #{}是sass的插值表达式
//& sass嵌套里的父容器标识 @content是混合器插槽,像vue的slot
[data-theme="#{$theme-name}"] & {
@content;
}
}
}

//声明一个根据Key获取颜色的function
@function themed($key) {
@return map-get($theme-map, $key);
}

//获取背景颜色
@mixin background_color($color) {
@include themeify {
background-color: themed($color)!important;
}
}

//获取字体颜色
@mixin font_color($color) {
@include themeify {
color: themed($color)!important;
}
}

//获取边框颜色
@mixin border_color($color) {
@include themeify {
border-color: themed($color)!important;
}
}

themeify方法用于获取HTML的data-theme值。
themed方法用于根据HTML的data-theme值及调用者传过来的key去_themes.scss里获取相应的颜色。

使用

1
2
3
4
5
6
7
8
9
10
<style lang="scss" scoped>
@import "@/style/_handle.scss";

.common-util {
font-size: 18px;
@include font_color("font_color1");
@include background_color("background_color1");
@include border_color("border_color1");
}
</style>

动态切换主题

1
2
3
4
//切换到 dark theme
window.document.documentElement.setAttribute( "data-theme", 'dark' );
//切换到 light theme
window.document.documentElement.setAttribute( "data-theme", "light" );
thank u !