环境
- 系统:
win10 64
- node版本
v16.13.2
- vue:
^3.2.33
- element-plus:
^2.2.0
开始
获取主题文件
- 文件内容太长了从示例仓库复制点击打开 或者直接拷贝仓库
themes.js
文件放到项目中。
- 当然这么多css 变量不是每个都需要改的,本文作为示例文章所以存入了全部的变量(能获取到的)。个人依实际情况进行删减保留!!!
根据主题类型使用函数进行动态切换加载css变量
- 项目中控制主题切换的地方引入上边获取到的
themes.js
(当然你的文件名字如果不是这个请根据实际情况来) 主题文件。
- 作者放在了
src -> utils -> themes.js
目录下,所以导入路径是import themes from '@/utils/themes'
。
src -> utils -> elCssVar.json
是获取的element-plus的css变量
- 通过
switchTheme函数
来控制主题的切换
data() {
return {
currentSkinName: 'darkTheme',
themeColorObj: {
defaultTheme: {
title: '浅色主题'
},
darkTheme: {
title: '深色主题'
}
},
themeObj: {}
};
},
mounted() {
this.switchTheme()
},
methods: {
switchTheme(type) {
this.currentSkinName = type || 'darkTheme'
this.themeObj = themes[this.currentSkinName]
this.getsTheColorScale()
Object.keys(this.themeObj).map(item => {
document.documentElement.style.setProperty(item, this.themeObj[item])
})
},
getsTheColorScale() {
const colorList = ['primary', 'success', 'warning', 'danger', 'error', 'info']
const prefix = '--el-color-'
colorList.map(colorItem => {
for (let i = 1; i < 10; i += 1) {
if (i === 2) {
this.themeObj[`${prefix}${colorItem}-dark-${2}`] = colorMix(this.themeObj[`${prefix}black`], this.themeObj[`${prefix}${colorItem}`], 1)
} else {
this.themeObj[`${prefix}${colorItem}-light-${10 - i}`] = colorMix(this.themeObj[`${prefix}white`], this.themeObj[`${prefix}${colorItem}`], i * 0.1)
}
}
})
}
}
colorMix函数
仓库示例是在 src -> utils -> tool.js
导出。
const colorMix = (color1, color2, weight) => {
weight = Math.max(Math.min(Number(weight), 1), 0)
let r1 = parseInt(color1.substring(1, 3), 16)
let g1 = parseInt(color1.substring(3, 5), 16)
let b1 = parseInt(color1.substring(5, 7), 16)
let r2 = parseInt(color2.substring(1, 3), 16)
let g2 = parseInt(color2.substring(3, 5), 16)
let b2 = parseInt(color2.substring(5, 7), 16)
let r = Math.round(r1 * (1 - weight) + r2 * weight)
let g = Math.round(g1 * (1 - weight) + g2 * weight)
let b = Math.round(b1 * (1 - weight) + b2 * weight)
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;
}
主题切换的一些疑问
切换主题的 css变量 是从哪里获取的?
- 打开 elementPlus-ui 官方网站 f12 审查元素。拿取所有 css变量。
switchTheme 函数中的获取基本色色阶是什么?
- 就是图片的里的变量,控制如navmenu导航 hover 的背景色等...
网站与主题颜色同步更改
- 项目内需要跟随主题改变的颜色,使用主题的css变量即可如:
更好的方式
- 在某个地方看到直接设置css变量会有性能问题
element-plus
的主题切换本身也不是直接设置css变量,而是在 html
标签上设置class
来实现。
大概实现
- 新建并在
main.js
中引入theme.css
--color: black;
.dark {
--color: red;
}
- 为
html
标签上设置对应的 class
。
- 根据
css权重
如果设置了对应的class则权重高的覆盖权重低的,从而实现主题切换。
参考文章
往期文章