一键更换ElementUI主题

539 阅读3分钟

项目中用了element-ui,有切换主题色的需要。

 

主要使用到的插件:

webpack-theme-color-replacer

join-file-content-plugin

element-theme-chalk

sass

sass-loader

 

主要原理是利用webpack插件webpack-theme-color-replacer提取相关颜色css然后根据配置动态生成替换的css

 

顾名思义,可以轻松实现整个项目主题颜色的替换。

引用下插件作者的思路:

基本思路就是,webpack构建时,在emit事件(准备写入dist结果文件时)中,将即将生成的所有css文件的内容中 带有指定颜色的css规则单独提取出来,再合并为一个theme-colors.css输出文件。然后在切换主题色时,下载这个文件,并替换为需要的颜色,应用到页面上。这样,下载的样式中就只包含颜色相关的css规则,文件较小;同时它已经包含了项目中所有的css中的指定颜色样式,一次下载全部颜色样式都搞定。

 

简介:

element-ui按需加载,主题色全局切换

css按需加载的来源直接指向element-ui的scss文件,而不是预编译的css文件。通过join-file-content-plugin插件在编译时将src/assets/css/element-theme/theme-changed.scss文件 附加到element-ui主题变量文件element-theme-chalk/src/common/var.scss之前,实现了在修改scss变量后即可立马查看效果,无需预先编译element-ui的scss文件为css文件。同时可以在项目任意地方引用element-ui的scss变量。

运行时动态调整主题色(含自写的主题样式)(链接为参考案例)

利用webpack-theme-color-replacer插件,在webpack构建时提取css中含有主题色的样式规则,生成一个css/theme-colors.css文件。然后在网页运行时,下载这个css文件,动态替换其中的颜色为自定义主题色。由于只提取了颜色相关的css,故速度比下载element-ui整个css要快很多。而且不仅仅是element-ui的样式,项目中的自写样式的主题色也可以一并替换掉。

 

具体实现步骤如下:

1、安装 webpack-theme-color-replacer (注意安装版本 V1.3.12)、安装 join-file-content-plugin、element-theme-chalk、sass、sass-loader

npm i webpack-theme-color-replacer@1.3.12 join-file-content-plugin element-theme-chalk sass sass-loader -D

 

2、添加css文件夹下element-var-changed.scss文件

$--color-primary 为主题色,可自主设置。该文件下的变量会通过join-file-content-plugin插件附加在‘element-theme-chalk/src/common/var.scss’中

//可在本文件中覆盖element-theme-chalk同名变量

//会将此文件附加在 "~element-theme-chalk/src/common/var.scss" 之前(通过join-file-content-plugin实现);

//覆盖主色

$--color-primary: #409EFF; //去掉 !default

$--color-primary-light-95: mix(#fff, $--color-primary, 95%);

$--color-primary-dark-1: mix(#000, $--color-primary, 10%);

$--color-primary-dark-2: mix(#000, $--color-primary, 20%);

 

3、在 vue.config.js添加插件

const ThemeColorReplacer = require('webpack-theme-color-replacer')

const forElementUI = require('webpack-theme-color-replacer/forElementUI')

const JoinFileContentPlugin = require('join-file-content-plugin')

let themeColor = '#409EFF'

module.exports = {

  configureWebpack: config => {

    // 需要 npm i -D webpack-theme-color-replacer

    const plugins = []

    plugins.push(

      // 将theme-changed.scss应用到element-ui,供babel-plugin-component按需加载

      new JoinFileContentPlugin({

        file: 'node_modules/element-theme-chalk/src/common/var.scss',

        prependFile: 'src/css/element-var-changed.scss'

      }),

      // 生成仅包含颜色的替换样式(主题色等)

      new ThemeColorReplacer({

        fileName: 'css/theme-colors.[contenthash:8].css',

        matchColors: [

          ...forElementUI.getElementUISeries(themeColor), // element-ui主色系列

          '#0cdd3a', // 自定义颜色

          '#c655dd'

        ],

        changeSelector: forElementUI.changeSelector,

        isJsUgly: isPro

        // injectCss: false,

        // resolveCss(resultCss) { // optional. Resolve result css code as you wish.

        //     return resultCss + youCssCode

        // }

      })

    )

    config.plugins = [...config.plugins, ...plugins]

  }

}

 

matchColors数组中可配置多个自定义要替换的主题色

 

4、.新建文件themeColorClient.js

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

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

export let curColor = '#409EFF'

// 动态切换主题色

export function changeThemeColor (newColor) {

  const options = {

    newColors: [...forElementUI.getElementUISeries(newColor), '#ff0000', '#ffff00']

  }

  return client.changer.changeColor(options, Promise)

    .then(t => {

      curColor = newColor

      localStorage.setItem('theme_color', curColor)

    })

}

export function initThemeColor () {

  const savedColor = localStorage.getItem('theme_color')

  if (savedColor) {

    curColor = savedColor

    changeThemeColor(savedColor)

  }

}
 

 

5、在需要的时候调用 initThemeColor初始化颜色 changeThemeColor改变主题颜色

import { initThemeColor,changeThemeColor } from './utils/themeColorClient'

initThemeColor()

changeThemeColor('#F56C6C')//传入颜色格式应该为十六进制颜色值,'red'类似颜色暂不支持