10

项目项目中用了element-ui,有切换主题色的需要。但官方的方式,有几个问题:
1、需要下载整个element-ui的样式css,并替换其中的css样式颜色。文件较大,下载慢且影响性能。
2、只能替换element-ui本身的颜色样式,项目中自己写的颜色样式替换不掉。
3、全部的element-ui样式都重新覆盖,渲染较慢,且容易导致覆盖已有样式出现意外问题。

其实带颜色的样式规则只占了所有css中很少的一部分。所以,我希望可以只替换css中与颜色相关的部分css规则。
于是花了半天时间,写了个webpack插件来实现这个功能。

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

经过反复测试,实现的效果比较理想。而且还可以根据需要,替换掉任意数目的颜色。理论上是只要是css的颜色,都可以通过这个插件来提取颜色样式。

为了方便使用,目前集成了element-ui的系列主题色获取方法(即根据主色得到同一色调由浅入深的一系列颜色)在组件里。代码已开源在github,欢迎fork并提交其他UI库的主题色获取方法。

分享给大家:

效果预览
插件源码
完整项目源码

效果:

原始顏色:

图片描述


切換後:

图片描述

适用场景

理论上,只要是使用webpack + css-loader来进行构建的项目,都可以用类似的方法来实现主题色动态切换。例如以下项目我有做了例子,可供参考:

ant-design:

https://segmentfault.com/a/11...

ant-design-vue

https://segmentfault.com/a/11...

iview

https://github.com/iview/ivie...


如果觉得我的文章对你有用,请随意赞赏

你可能感兴趣的

31 条评论
smile · 1月18日

你的项目 clone 下来 切换颜色 失效的!

回复

0

我又试了试可以的。请检查你的步骤,如果有错误信息还请贴出来

okfine 作者 · 2月13日
Spring · 2月14日

作者您好,项目下载下来本地运行没有问题,但是打包后themeColor.html报错,报错信息为Uncaught ReferenceError: platInfo is not defined

回复

0

你好,原因找到了,已修复。谢谢!

okfine 作者 · 2月15日
0

然后颜色切换不了了

Spring · 2月15日
0

@Spring 刚在这重新拉代码执行npm run build-test发布后,可以切换的:http://test.hz300.com/webpack...

okfine 作者 · 2月15日
ci0n · 2月21日

一定要是element-ui的吗?

回复

okfine 作者 · 2月21日

不是,插件只要是webpack都行,移动端也可以。element-ui这个是例子

回复

妖类 · 3月22日

这个插件支持typeScript语言吗

回复

妖类 · 3月22日

我项目中用的是typeScript,想借用这个插件换主题

回复

0

理论上只要是webpack用了css-loader的都可以,如果不行欢迎上github提

okfine 作者 · 3月30日
追风 · 4月16日

customcolor 切换不了

回复

0

需要配置的,可参考例子。

okfine 作者 · 4月19日
0

我也是custom-color切换不了,怎么配置能说一下吗?多谢!

茂仔1991 · 4月22日
0

参考这两个文件:
https://github.com/hzsrc/vue-...
https://github.com/hzsrc/vue-...

或者直接传完整的数组,参考:
https://github.com/hzsrc/webp...

okfine 作者 · 4月26日
3762 · 5月24日

请问楼主,我没找到入你这个demo的,可以根据选色器去 定义主题的配置。只看到了固定的 var options = {

    primary: {
        oldColor: oldColor || appConfig.themeColor,
        newColor: newColor,
    },
    cssUrl: appConfig.themeFile,
    others: {
        oldColors: ['#0cdd3a', '#c655dd'],
        newColors: ['#ff0000', '#ffff00'],
    }
},

回复

0

這個是element-ui用的。你可以參考文檔:https://github.com/hzsrc/webp...

okfine 作者 · 5月24日
肥小虫 · 5月30日

用到了 点赞

回复

肥小虫 · 6月4日

你好,我项目在本地可以换肤,build之后自定义组件中用到的主题色 $--color-primary 没有动态生成到style中去,请问知道是什么原因吗,我试了你的demo是可以的

回复

0

推测是demo中的build/make-element-theme你的项目没有,你看下

okfine 作者 · 6月4日
0

@okfine 是的,因为配置的时候老报错而且我本地可以换肤就被我注释掉了,请问这个一定要配吗,我把你demo中这个文件给注掉之后,打包后还是可以换肤的,现在有点懵。。

肥小虫 · 6月4日
0

@okfine 我现在发现是因为我自定义组件中用到主题色变量的样式没有打到theme-colors.css里去,所以导致换肤没反应,但是element组件是可以换肤的,请教这个怎么解决,谢谢

肥小虫 · 6月4日
useryechen · 5 天前

作者您好,我现在也遇到了类似的问题,不同的是,我有一个后台管理系统,用户通过后台管理系统的选色卡选择好主题色。还有一个前台商城,在前台商城中要显示后台管理系统中配置的主题色。你这种情况是在打包的时候解决的,但是我这个是sass平台,不能通过这个思路来解决。请问您有什么好的建议吗

回复

0

关键看有没有前后端分离,前端用webpack的就行。不分离的要么动态生成css,要么做几套主题供选

okfine 作者 · 4 天前
0

@okfine 项目是前后端分离,但是这个色值是从一个后台管理系统中选择的,前台商城只是从数据库中读到色值,然后渲染主题色,目前的做法是预设几套主题色,但是有客户建议后台管理系统中使用取色器去获取色值

useryechen · 1 天前
载入中...