0 环境
1 参考文档
2 前言
主要是围绕ThemeDrawer/index.vue
里的全局主题,就是主题颜色、暗黑模式、灰色模式、色弱模式,如下图,这四种模式关联事件,changePrimary
、暗黑模式有点特殊,看上去它是一个组件,但你点进SwitchDark
组件进入,其本质还是触发了switchDark
,只不过多了层封装罢了。灰色模式和色弱模式用的是changeGreyOrWeak
,下面的正文就是分析这三个。
3 正文
1 changePrimary
先看ThemeDrawer/index.vue
中的changePrimary
,它是为了修改主题颜色,就是选中个颜色,它是个十六进制,然后点击确定。
具体代码如下: <el-color-picker v-model="primary" :predefine="colorList" @change="changePrimary" />
这里的primary
它是来自于useGlobalStore
,点进useGlobalStore
,你会看到primary: DEFAULT_PRIMARY,
,它有一个默认颜色,点进DEFAULT_PRIMARY
,它的默认值是#009688
,是不是就对应上图了那个十六进制的值了,不喜欢默认色的,可以在这里的进行修改。
changePrimary
是怎么做到颜色的转换的呢,点进changePrimary
,代码如下图:
没有值的情况下,就是默认值。然后设置style属性
,将val的值传给--el-color-primary
。
--el-color-primary-dark-2
这里是需要判断的,这里isDark.value
其实是跟暗黑模式有关,假如开启了暗黑模式,调用getLightColor
,否则调用getDarkColor
。看看它俩做了些什么,getLightColor
是变浅颜色值,如下图代码:
比如getLightColor(val, 0.2)
,先判断是不是十六进制,hexToRgb
将十六进制转RGB(比如#FFB6C1
被转成255,182,193
),如下第二张图代码,是否是十六进制的判断,去掉#,剩余的两两字符切割,然后转成数字替换,返回hexs数组。
然后for循环,Math.round
计算,这里是一个亮度级别计算(第二个入参),将最终结果在转成十六进制。rgbToHex
看下面第三张图片的代码,目的就是rgb转十六进制,先判断rgb格式对不,然后转成十六进制,最后连一起返回。getDarkColor
类似就不再重复了。
回到changePrimary
实现上去,这里加了--el-color-primary-light1、2...
数字的属性,颜色对应不同的亮度级别。
ini
for (let i = 1; i <= 9; i++) {
const primaryColor = isDark.value ? `${getDarkColor(val, i / 10)}` : `${getLightColor(val, i / 10)}`;
document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, primaryColor);
}
将primary
的值更新到globalStore
上。
2 SwitchDark组件
在ThemeDrawer/index.vue
中找到SwitchDark
组件,点进去,代码如下图:
也是开关按钮,绑定的是globalStore
里的isDark
,它的初始值是false
,inline-prompt :active-icon="Sunny" :inactive-icon="Moon"
,将这两个图标放在开关中。点进switchDark
,代码如下图:
isDark
为真,html
中加入类名为dark
,否则为空。对应的dark
的scss在src/styles/element-dark.scss
中`。
代码如下图:
这里主要针对登录页的暗黑配置。
changePrimary
主题色受到影响的是--el-color-primary-dark-2
和--el-color-primary-light-数字
。setAsideTheme、setHeaderTheme、setMenuTheme
都它们的type
为"dark"
。得到xxxTheme
里对应Theme
的值。具体它们在哪里被引用,不用多说了。
3 changeGreyOrWeak
灰色模式和色弱模式共用changeGreyOrWeak
,解释一个就可以了。在ThemeDrawer/index.vue
中找到<el-switch v-model="isGrey" @change="changeGreyOrWeak('grey', !!$event)" />
,全局绑定的是isGrey
,默认是false
。changeGreyOrWeak('grey', !!$event)
这里的第二个参数是一个布尔值,这个布尔值是通过对$event
进行逻辑非(!!
)运算得到的,也就是对应的value: boolean
,看下图代码实现的入参。
下图:
value为假时,移除style
,看下面第二张图,body.setAttribute
根据type
的类型传给style
。最后的代码意思就是灰色和弱色模式互斥。
4 总结
修改主题颜色,其实和之前的类似,往style里加入或更新值。这里有点特殊的是
getLightColor
和getDarkColor
的实现,先将十六进制转成rgb,与level相运算后,在转成十六进制。暗黑模式设置的.dark
,改变的是登录页的模式,但是主页内容是由changePrimary、setAsideTheme、setHeaderTheme以及它们里的setMenuTheme
,目的是拿到xxxTheme
对应的dark
的值,通过值来改变页面的。灰色和弱色模式,它俩互斥,没有太多的修改就是body style
里塞入一行css
,不存在value
就移除style
。