vue + element-UI 实现深色模式和主题色动态切换
文章目录
- vue + element-UI 实现深色模式和主题色动态切换
-
- 前言
- 深色模式和主题色动态切换
-
- 本地样式切换
- 主题色切换
- element样式切换
- 总结
首先说明一下,我对前端了解的不多,最近因为报的项目问题才临时学的vue(之前也用过一次),然后就套用了ruoyi-vue的板子,这是ruoyi项目源码的地址和实现效果预览的地址,这篇文章主要只是给大家提供了一个思路,多半不会是最优解前言 我看了ruoyi项目之后,感觉被它的可以切换主题色惊艳到了(当然其他也是,如代码生成,动态路由等等),但是它虽然做了深色模式,但是深色模式只涉及了菜单这一块,而主页内容却没有改变,且深色模式侵入到了各种vue代码中。我就产生了一些想法。
深色模式和主题色动态切换 这里的切换主要分成了三块:
- 本地样式的切换
- 主题色的切换
- element样式的切换
文章图片
也就是ruoyi项目中对应的主题风格和主题颜色
本地样式切换
本地样式切换我用了一个比较阴间的实现方式,会导致所有与主题风格相关的样式(颜色)代码不得不写入到外部scss文件中,而不能直接写在vue文件内,会导致vue的scope特性无法发挥,使vue组件重用性的优点很大程度受到影响。
我的实现方式:
// 将#app的div的类型与theme绑定,在不同的域下面导入不同的主题颜色变量,
// 再导入需要这些变量的总体的样式文件
// app.scss
#app.theme-standard{
@import "./theme/theme-standard";
@import "app-base";
}#app.theme-light{
@import "./theme/theme-light";
@import "app-base";
}#app.theme-dark{
@import "./theme/theme-dark";
@import "app-base";
}
// theme-standard.scss
$menu-text:#bfcbd9;
$menu-active-text: #ffffff;
$sub-menu-active-text:#f4f4f5;
//https://github.com/-eleme-f-e/element/issues/12951
$menu-bg:#404040;
$menu-hover:#263445;
$menu-focus:#152334;
// app-main.scss
.app-container{
background: $app-bg;
}
这种玩法后患无穷,绝对不要试。 而且也无法导出变量给js使用。我写在这边完全是因为我真的为了想到这个花了好长时间,就算有问题还是难免想记录一下。
推荐的办法:
- 一种像ruoyi一样,导出其他样式的scss中的变量,vue文件中引用这些变量来进行设置,而且如果用了computed的话,代码上也不会特别难看
- 看链接
主题色的实现方式
- 申请新的element样式,替换掉该主题色的值,写入到style中
- 从App.vue中设置color为主题色,这样后续就可以使用currentColor来设置颜色
但是还有一个问题,element-ui有很多hover,active时会有基于主题色变淡的颜色还有阴影色等。
这就得看element是如何生成这些颜色的,总的来说:
- 10级向浅色渐变
- 0.9倍阴影色
// 浅色渐变方法
tintColor = (color, tint) => {
red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue))
return `#${red}${green}${blue}`
}
// 阴影色方法
shadeColor = (color, shade) => {
red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue)
return `#${red}${green}${blue}`
// 生成颜色集群
for (let i = 0;
i <= 9;
i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
}
clusters.push(shadeColor(theme, 0.1))
}
// 替换掉所有 #409EFF 生成的cluster 成 我们要的主题色生成的cluster
let newStyle = style
oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
})
// 写入到样式中
let styleTag = document.getElementById(id)
if (!styleTag) {
styleTag = document.createElement('style')
styleTag.setAttribute('id', id)
document.head.appendChild(styleTag)
}
styleTag.innerText = newStyle
element样式切换
这是ruoyi没有做的,因为没有修改element背景色之类的需求,如果我们要做深色模式就得修改element的颜色。
然后我们就得定制样式文件,但是我的办法貌似并不是element推荐的。。。
办法就是修改刚才的element样式,定制出各个主题版本,主要修改背景色、边框颜色和字体颜色
效果大概是
文章图片
但是可能会出现这种突然特别亮的阴间配色,这些颜色会出现在10级浅色渐变,默认的10种颜色就是
[
"409EFF",
"64,158,255",
"#53a8ff",
"#66b1ff",
"#79bbff",
"#8cc5ff",
"#a0cfff",
"#b3d8ff",
"#c6e2ff",
"#d9ecff",
"#ecf5ff",// 这个注意一下噢
"#3a8ee6"
]
只要在这10种颜色中找出,切换成灰色就可以比较ok了,其实还是有点阴间。。。看大家配色的功夫了。。。
文章图片
总结 我主要想讲的就是如何动态切换主题的,实现方式是请求样式文件,多半是会一定程度上导致白屏。。。反正就是这样,我就提供一个思路啊
推荐阅读
- vue|vue+element项目动态添加删除数据div
- 突发奇想|Vue + Element做个个人中心玩玩~
- Vue|ES6学习——一文搞懂ES6
- 笔记|电话面试-----海康威视
- 面试|海康威视电话面试
- Vue的计算属性
- vue|一篇文章汇总git常用命令
- vue|websocket的简单应用
- 前端|我的前端之路