结合elementui实现的动态主题
# 前言
切换主题在管理系统中是一个常见的功能,本文将结合
elementui
来实现一个切换主题的功能
# css变量
css
变量非常适合用于做样式的批量替换。elementui
本身也是通过css变量
来实现的不同主题的定制效果。对css变量
不了解的可以自行了解一下,使用起来还是非常简单的。
# 具体做法
elementui
使用了一下几个变量作为整个组件库的主色
调和辅色
--el-color-primary: #4165d7;
--color-primary: #4165d7;
--el-color-primary-light-1: #5474db;
--el-color-primary-dark-1: #3b5bc2;
--el-color-primary-light-2: #6784df;
--el-color-primary-dark-2: #3451ac;
--el-color-primary-light-3: #7a93e3;
--el-color-primary-dark-3: #2e4797;
--el-color-primary-light-4: #8da3e7;
--el-color-primary-dark-4: #273d81;
--el-color-primary-light-5: #a0b2eb;
--el-color-primary-dark-5: #21336c;
--el-color-primary-light-6: #b3c1ef;
--el-color-primary-dark-6: #1a2856;
--el-color-primary-light-7: #c6d1f3;
--el-color-primary-dark-7: #131e40;
--el-color-primary-light-8: #d9e0f7;
--el-color-primary-dark-8: #0d142b;
--el-color-primary-light-9: #ecf0fb;
--el-color-primary-dark-9: #060a15;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
而我们要做的就是在切换主题后根据一个主色调计算出其他的辅色然后把这些个变量覆盖
掉就好了。
计算色值的函数如下
function mix(color1: string, color2: string, weight: number) {
weight = Math.max(Math.min(Number(weight), 1), 0)
const r1 = parseInt(color1.substring(1, 3), 16)
const g1 = parseInt(color1.substring(3, 5), 16)
const b1 = parseInt(color1.substring(5, 7), 16)
const r2 = parseInt(color2.substring(1, 3), 16)
const g2 = parseInt(color2.substring(3, 5), 16)
const b2 = parseInt(color2.substring(5, 7), 16)
let r = Math.round(r1 * (1 - weight) + r2 * weight).toString(16)
let g = Math.round(g1 * (1 - weight) + g2 * weight).toString(16)
let b = Math.round(b1 * (1 - weight) + b2 * weight).toString(16)
r = ('0' + (r || 0).toString(16)).slice(-2)
g = ('0' + (g || 0).toString(16)).slice(-2)
b = ('0' + (b || 0).toString(16)).slice(-2)
return '#' + r + g + b
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
第一个参数传入我们的主色
第二次参数可以传入黑色或白色作为辅色
,这样就可以根据偏移量
计算出基于主色演变出来的深色或浅色
剩下的事情就简单了,只需要在切换主题的时候拿到主色然后把生成出的颜色加入到html
中就可以了
function setTheme({
color, name,
}: Theme) {
// const { app } = useNotCool()
const { get, set } = useLocalStorage('theme')
// 主题配置
const theme = get() || {}
// 变量前缀
const pre = '--el-color-primary'
// 白色混合色
const mixWhite = '#ffffff'
// 黑色混合色
const mixBlack = '#000000'
// 元素
const el = document.documentElement
// 主题
if (name) {
const item = themes.find((e) => e.name == name)
if (item) {
if (!color) {
color = item.color
}
}
document.body?.setAttribute('class', `theme-${name}`)
theme.name = name
}
// 设置主色
if (color) {
el.style.setProperty(pre, color)
el.style.setProperty('--color-primary', color)
// 设置辅色
for (let i = 1; i < 10; i += 1) {
el.style.setProperty(`${pre}-light-${i}`, mix(color, mixWhite, i * 0.1))
el.style.setProperty(`${pre}-dark-${i}`, mix(color, mixBlack, i * 0.1))
}
theme.color = color
}
set(theme)
}
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
42
43
44
45
46
47
48
49
50
51
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
42
43
44
45
46
47
48
49
50
51
这里有一个存入缓存
和取缓存
的操作,是为了刷新
后不丢失之前选择的样式。
# 拓展
可以参考element
的做法通过css
变量确定自己网站的整体颜色基调,这样后续切换主题会非常方便。其实还可以通过给所有类名加不同的父类名来进行主题切换,但是这种方案要预设主题,不灵活。而且要写很多样式,也非常的不方便。所以综合下来还是css变量
最好用!
编辑 (opens new window)
上次更新: 2023/09/06, 09:59:30