首先说明一下,我对前端了解的不多,最近因为报的项目问题才临时学的vue(之前也用过一次),然后就套用了ruoyi-vue的板子,这是ruoyi项目源码的地址和实现效果预览的地址,这篇文章主要只是给大家提供了一个思路,多半不会是最优解
我看了ruoyi项目之后,感觉被它的可以切换主题色惊艳到了(当然其他也是,如代码生成,动态路由等等),但是它虽然做了深色模式,但是深色模式只涉及了菜单这一块,而主页内容却没有改变,且深色模式侵入到了各种vue代码中。我就产生了一些想法。
这里的切换主要分成了三块:
我在store中记录了theme和theme_color这两个值,我将深色模式视为一个主题,对应的也有标准和浅色模式,用theme来记录,theme_color记录的则是主题色
也就是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使用。我写在这边完全是因为我真的为了想到这个花了好长时间,就算有问题还是难免想记录一下。
推荐的办法:
<el-menu
:background-color=
"settings.sideTheme === 'theme-dark' ? variables.menuBg : variables.menuLightBg">
</el-menu>
<
主题色的实现方式
首先可以看一下 element返回的样式,里面默认的主题色是#409EFF,只要换成我们要的主题色就行了。
但是还有一个问题,element-ui有很多hover,active时会有基于主题色变淡的颜色还有阴影色等。
这就得看element是如何生成这些颜色的,总的来说:
// 浅色渐变方法
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
这是ruoyi没有做的,因为没有修改element背景色之类的需求,如果我们要做深色模式就得修改element的颜色。
然后我们就得定制样式文件,但是我的办法貌似并不是element推荐的。。。
办法就是修改刚才的element样式,定制出各个主题版本,主要修改背景色、边框颜色和字体颜色
效果大概是
但是可能会出现这种突然特别亮的阴间配色,这些颜色会出现在10级浅色渐变,默认的10种颜色就是
[
"409EFF",
"64,158,255",
"#53a8ff",
"#66b1ff",
"#79bbff",
"#8cc5ff",
"#a0cfff",
"#b3d8ff",
"#c6e2ff",
"#d9ecff",
"#ecf5ff", // 这个注意一下噢
"#3a8ee6"
]
只要在这10种颜色中找出,切换成灰色就可以比较ok了,其实还是有点阴间。。。看大家配色的功夫了。。。
我主要想讲的就是如何动态切换主题的,实现方式是请求样式文件,多半是会一定程度上导致白屏。。。反正就是这样,我就提供一个思路啊