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

2,391 阅读4分钟

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

一套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函数去执行命令行,即

lessc -x custom.less styles.css

custom.less入口文件所引用的所有组件样式整体编译为一个styles.css

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

可能存在的问题

  • 效率, 如果组件特别多,lessc compiler 过程的速度,我并没有测试过,会不会太长而影响用户体验。不过可以通过进度条提示主题更新的进度,这也是Element UI 网站所采用的策略

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

所以对于懒加载路由(包含js和css),需要额外的资源去做新主题样式的编译,这也是需要权衡的。

[Theme Switcher项目地址](github.com/alex2wong/t…

写在最后

发一个福利贴: 🚀我们是抖音音乐研发团队,我们需要支撑的产品有抖音这款数亿日活用户的产品,也有一款已经在海外多个国家上线的独立音乐产品 Resso

我们不仅需要有经验的同学,也需要刚毕业的同学们~ 面试的话,对候选人的算法能力有一些要求,我们考察的是候选人的问题解决能力、计算机基础等方面、思考习惯等

就前端来讲,工作内容包括:

  • 负责抖音相关产品功能开发,包括用户产品端功能、大型活动、小程序等的开发;
  • 负责抖音相关中台、业务平台、ToB产品的全栈技术方案设计、开发;
  • 负责基础框架、工具链、组件库等基础设施设计、开发和维护;
  • 跨端及全栈、音视频等技术方向进行核心难题攻坚;

感兴趣的同学可以点击投递:job.toutiao.com/s/JbLRbqPjo… 或者发简历到 huangyixiu@bytedance.com 并注明岗位。我会跟踪进度哦~

参考文章

Ant design 的自定义主题

Element 组件库的整体设计

LESS 用法