基于element-plus如何更换主题?

2,649 阅读3分钟

基于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 进行覆盖 然后替换。

image-20220819143307242.png

  • 第二种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文件,取名叫随便我的叫这个

image-20220819151014776.png 其实也是复制粘贴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` 库来生成颜色,在默认的样式中进行替换。这是主要的代码,有需要全部代码的请留下你的联系方式,或者关注我私信我谢谢。

image-20220819153235061.png

总结

世上无难事,只要你肯放弃。加油你还年轻。