自定义 element-ui 的主题

前言

项目采用的是 vue-admin-template 框架搭建的,因为常年用 react 开发不是很熟悉,还在慢慢摸索呢,就很突然接到一个需求说要动态修改主题色,然后疯狂的上网查询......

1、使用全局样式覆盖(做到一半放弃了,这就不是人干的事!😭)

2、使用官方提供的在线主题编辑器下载后进行替换(编译后无法修改)

3、通过改变 element-ui 的样式变量(无法将变量通过js传入)

先创建一个 element-variables.scss 的文件,内容如下:

/* 改变主题色变量 */
$--color-primary: teal;

/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';

@import "~element-ui/packages/theme-chalk/src/index";

在项目的入口文件 main.js 中,直接引入以上样式文件即可(无需引入 Element 编译好的 CSS 文件):

import Vue from 'vue'
import Element from 'element-ui'
import './element-variables.scss'

Vue.use(Element)

但是上面的方案都无法满足编译后修改element-ui主题,最终找到webpack-theme-color-replacer解决。

步骤一

安装 webpack-theme-color-replacer

npm install --save webpack-theme-color-replacer@1.3.22(安装最新版本会报错,暂未找到解决方案)

步骤二

在 vue.config.js 中进行配置

chainWebpack: config => {
    // 自定义换肤
    config.plugin('webpack-theme-color-replacer')
      .use(ThemeColorReplacer)
      .tap(options => {
        const matchColors = []
        // 官网默认主题的5种按钮颜色
        const data = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399']
        data.forEach(item => {
          matchColors.push(...forElementUI.getElementUISeries(item))
        })
        options[0] = {
          fileName: 'css/theme-colors-[contenthash:8].css',
          matchColors: matchColors,
          changeSelector: forElementUI.changeSelector,
          isJsUgly: process.env.NODE_ENV !== 'development'
        }
        return options
      })
  }

步骤三

新建一个 themeColor.js 文件用来初始化和切换主题色

import client from 'webpack-theme-color-replacer/client';
import forElementUI from 'webpack-theme-color-replacer/forElementUI';

// 动态切换主题色
export function changeThemeColor(colorList) {
    const data = [];
    try {
        const list = JSON.parse(window.localStorage.getItem('color'));
        list.forEach(item => {
            data.push(...forElementUI.getElementUISeries(item));
        })
    }catch {
         colorList.forEach(item => {
            data.push(...forElementUI.getElementUISeries(item));
        })
    }
    return client.changer.changeColor({ newColor: data }, Promise);
}

export function initThemeColor() {
    changeThemeColor(['#409EFF','#67C23A','#E6A23C', '#F56C6C', '#909399'])
}

步骤四

在 main.js 文件中引用 initThemeColor 的方法

import Vue from 'vue';
import ELEMENT from 'element-ui';
import { initThemeColor } from './component/themeColor.js';
initThemeColor();

Vue.use(ELEMENT);

特别注意

颜色列表要一一对应,不然会出现颜色错乱的现象!

posted @ 2022-06-28 15:45  蹦跶的比丢  阅读(1455)  评论(0编辑  收藏  举报