如何动态自定义webapp全局主题

前几天看到一个问题,挺多人问:一个web app 的动态自定义主题如何实现,意思是用户在webapp 中自定义一套配色,整个网站(包括全部组件)的主题相应变化如何实现?由于正好是在黄轶大佬的Element组件库揭秘的文章中看到相关内容,虽然大佬没有给出后端实现,但实际上方案已经很明确了。因此我拿node.js搭配vue-cli 简单快速地实现了一遍动态定义webapp全局主题的思路。css

一套LESS,动态编译

动态自定义主题workflow
简单说下,流程如上图,用户在前端配置一套主题以后,把颜色配置发给后端服务。后端最关键的阶段是拿到颜色配置,而后找到 存储颜色变量的less文件,重写颜色,生成新的less 文件,再编译全部的less 样式文件为一个css文件。

具体到咱们的例子,我把颜色变量放在customTemplate.less 中,这个文件和前端项目实际用的less 文件是同一套,除了颜色变量是 $primary ,$primary-color 等等样式,为了方便脚本中去替换。通常地,变量都定义在vars.less,入口文件是index.less,组件的样式定义在单独的模块中。这里为了快速演示就写到一个文件里了。前端

在咱们的例子中,node.js脚本中替换了 $primary ,$primary-color,把新的样式写入custom.less 中,而后再经过node.jsexec函数去执行命令行,即vue

lessc -x custom.less styles.cssnode

custom.less入口文件所引用的全部组件样式总体编译为一个styles.cssgit

到这一步,咱们就生成了新的自定义样式。接着,经过请求返回给浏览器,前端逻辑中会建立一个新的style标签,填入返回的css,插入<head> 标签的最后一行。这会直接overwrite前一套样式,由此就完成了动态自定义webapp主题。github

可能存在的问题

  • 效率, 若是组件特别多,lessc compiler 过程的速度,我并无测试过,会不会太长而影响用户体验。不过能够经过进度条提示主题更新的进度,这也是Element UI 网站所采用的策略web

  • 懒加载组件,目前我只是用了多个路由去简单测试多组件在动态主题切换中,会自动根据全局主题色去更新本身内部的样式。若是采用懒加载策略,理论上在切换主题后,若是点击到从未加载过的路由,该路由内部的样式会处于上一个主题色,应该会出现不一致。也就是说在接受到自定义主题请求后,若是server不针对该用户从新编译懒加载路由样式的服务,那这个样式不一致的问题就会出现!vue-cli

因此对于懒加载路由(包含js和css),须要额外的资源去作新主题样式的编译,这也是须要权衡的。后端

Theme Switcher项目地址浏览器

参考文章

Ant design 的自定义主题

Element 组件库的总体设计

LESS 用法

相关文章
相关标签/搜索