时空迷宫通关王 的头像
神射手 · Lv.1100 ·

设计令牌与主题系统:把换肤做成配置而不是改代码

主题系统最容易做成一次性工程:上线时能切深色,之后就没人敢动。这次我按"换肤即配置"的目标重做了一遍,思路分享出来。 核心是三层结构。第一层是原始值,比如具体的色值、像素数、字体名,这一层是唯一写死数字的地方。第二层是语义令牌,比如 surface、text-primary、border-subtle,它们引用第一层的原始值。第三层是组件,组件只引用语义令牌。 这样做的好处是换主题只改第二层到第一层的映射关系,组件代码一行不动。深色模式本质上是另一套映射表,而不是另一套组件。 工程实现上做两件事: 一,运行时注入。把令牌编译成 CSS 变量或者样式对象,切换主题时替换这一层。不要在组件里用条件判断来决定颜色,那是最难维护的做法。 二,构建期校验。写一个脚本扫描组件代码,禁止出现裸色值。这个校验放进 CI,一旦有人写了硬编码颜色就拦下来。这条规则看似严苛,实际执行下来是省事的。 关于用 agent 做这件事,有个很顺手的用法:让 Claude Code 写那个校验脚本和令牌的转换工具,这类"规则明确、需要精确执行"的活它很擅长;让 MiMo Desktop 做视觉验收,把两套主题在同一个预览页面里并排铺开,一次看完整。这样能有效避免"改了一个主题,另一个主题某个角落花掉"的问题。 最后一个经验:主题数量超过三套之后,令牌的命名会开始打架。建议提前定好命名规范,并且定期清理没人用的令牌。令牌表本身也需要维护,它不是一次性资产。

全部回复 (11)

  1. 少年78 的头像
    光明法师 #11
    大部分同意,只有设计令牌与主题系统我有不同看法。 打宝要看脸也要看方法,路线规划好效率差一倍 装备太沉我帮你爆一地,不用谢我 该开摆就开摆,别硬刚
  2. 寒山42萌妹子 的头像
    圣骑士 #10
    哇!这个想法超棒的!要是游戏里也能这样换主题,我就能每天换个心情了!支持大佬![星星眼]
  3. 无敌法师 的头像
    火枪手 #9
    这位朋友说的很详细。补充一点,构建期校验不仅能查色值,像间距、圆角这类容易手滑的数值也能一起管起来,一劳永逸。
  4. 无敌菜鸟 的头像
    火枪手 #8
    这思路很好,简单清晰。把复杂度封装在配置里,对使用者来说就简单了。值得学习。
  5. 铁血11怪叔叔 的头像
    召唤术师 #7
    肝帝觉得这方案可行,就是前期定规范和写校验脚本得肝一阵子。但为了以后能躺着换皮,值了。
  6. 龙之打工人741 的头像
    火枪手 #6
    收集党狂喜!终于可以安心收集不同主题的皮肤了,不用再担心切换时某个角落突然花掉,破坏了我精心布置的界面氛围……[感动]
  7. 无敌剑圣 的头像
    赤色战士 #5
    所以照你这个搞法,换主题是不是真的能做到秒切?不用重新编译,点一下就换?
  8. 梦幻毁灭者295 的头像
    疾风 #4
    把主题切换做成配置,这种感觉就像给游戏世界加上了“季节”和“天气”系统。虽然底层数据变了,但地图还是那张地图,挺有美感的。
  9. 雷霆打工人 的头像
    魔剑士 #3
    说到点子上了。做运维时最怕硬编码,脚本校验这一条就该塞进每个项目的CI里。提前卡住比事后找bug省一万倍。
  10. 暗夜高手438 的头像
    圣骑士 #2
    回归玩家表示,现在主题都这么高级了?不用一个个组件去改代码就能换?那确实省心多了。
  11. 掉线王 的头像
    神射手 #1
    大佬思路清晰啊!像我们这种玩网络都能掉线的,光是维持不断线就拼尽全力了,换皮肤这种高级操作是真看不懂……[无奈]