基于element-plus如何更换主题?
摘要
一个项目中使用了
element-plus
ui框架,当我们项目需要更换主题的时候项目中的组件如何自动替换主题,以及如何换肤。实现的方法有很多种在这里我简单介绍一下我知道的几种方法。废话不多说请听我继续废话🙈
更换主题的解决方案
通过 SCSS 变量
通过 生成css文件引入index.html 已被废弃。
通过 css变量
通过正则覆盖
element-plus/dist/index.css
中的css变量然后引入你的index.html
中的head中
-
第一种element-plus 这是官方给的一个换主题的案例,如果你的项目种只需要一种主题颜色的话这种很适合你,但往往项目种需要动态的替换主题色,这种方案就不太行,我暂时没有找到解决的方法,有厉害的小伙伴可以解决一下,他是怎么替换的呢?
-
基于sass变量进行覆盖方法,element-plus官方人员对项目的样式重新进行了架构通过sass中的sass-map的用法 有点类似与JavaScript中的Object 只不过是用的()包裹。
-
map 的方法
$font-weights: ("regular": 400, "medium": 500, "bold": 700); $heavy-weights: ("medium": 500, "bold": 700); @debug map.set($font-weights, "extra-bold", 900); // ("regular": 400, "medium": 500, "bold": 700, "extra-bold": 900) @debug map.set($font-weights, "bold", 900); // ("regular": 400, "medium": 500, "bold": 900) @debug map.merge($light-weights, $heavy-weights); // ("lightest": 100, "light": 300, "medium": 500, "bold": 700)
-
回到正题是这种方法是如何替换呢?
-
我们看到使用 @forward 进行覆盖 然后替换。
-
-
-
第二种
element-plus
低版本的小于等于elment-plus@1.0.2-bate.54
版本的可以直接引入element-plus/packages/theme-chalk/src/index
然后将你替换的主题进行引入通过shell脚本重新生成css文件,然后在你的index.html
文件引入这个样式文件动态的替换这个css文件就可以实现。但是不幸的是这种方法已被废弃不建议使用。有需要方法的可以下方留下留下你的联系方式。 -
第三种是值得推荐的方法,也有缺陷,有些地方样式还是需要手动覆盖,改不完全,但是很实用,程序员就是为了bug而生的不是吗,没有bug还叫程序吗?废话不多说请看代码。
:root{ --el-color-primary: green; }
// document.documentElement 是全局变量时 const el = document.documentElement // const el = document.getElementById('xxx') // 获取 css 变量 getComputedStyle(el).getPropertyValue(`--el-color-primary`) // 设置 css 变量 el.style.setProperty('--el-color-primary', 'red')
这是官方给的示例,看着简单不知道怎么下手?懂得话就不需要往下看了,下面是详细教程比较啰嗦。
-
我们需要在项目中新建一个scss文件,取名叫随便我的叫这个
-
其实也是复制粘贴element-plus
里面的css变量😁 这些名字可以自己随意起名就行我值也可以通过变量命名再取值,我难得弄就和element-plus
一样了最后引入你的main.js
封装统一的方法方便调用
type StringNumber = string | number export const mix = (color1: string, color2: string, weight: StringNumber) => { 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: StringNumber = Math.round(r1 * (1 - weight) + r2 * weight); let g: StringNumber = Math.round(g1 * (1 - weight) + g2 * weight); let b: StringNumber = 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; }; // 改变主题 export function changeTheme(color: string) { const node = document.documentElement // 变量前缀 const pre = '--el-color-primary' // // 白色混合色 // const mixWhite = '#ffffff' // // 黑色混合色 // const mixBlack = '#000000' node.style.setProperty(pre, color) setTheme(color) node.style.setProperty('--el-color-primary', color) // 这里是覆盖原有颜色的核心代码 for (let i = 1; i < 10; i += 1) { node.style.setProperty(`${pre}-light-${i}`, mix(color, mixWhite, i * 0.1)) node.style.setProperty(`--el-color-primary-dark-${i}`, mix(color, mixBlack, 0.1)) }
上面一共两个函数一个
mix
函数一个changeTheme
函数mix函数类似与sass中的mix,rgba
函数用于生成颜色用的。changeTheme
函数则就是为了改变变量的操作。这个方法是有缺陷的,对于一个el-link,el-button
的一些样式会需要再次覆盖,但没办法的办法就是好办法。。。 -
最后一种方法有点复杂,原理就是通过用正则匹配
elment-plus
中的css变量然后用js使用rgbHex
css-color-function
库来生成颜色,在默认的样式中进行替换。这是主要的代码,有需要全部代码的请留下你的联系方式,或者关注我私信我谢谢。 -
-
总结
世上无难事,只要你肯放弃。加油你还年轻。