唯一全端可靠的动态换肤方案是用 document.documentElement.style.setProperty() 修改 CSS 自定义属性;其他方式在 App 或小程序中普遍失效,因 runtime 不支持 styleSheets 操作且不触发重排重绘。

直接用 document.documentElement.style.setProperty() 修改,这是唯一全端可靠的方案。其他方式在 App 或小程序里大概率失效。
为什么不能操作 document.styleSheets 或 insertRule
App 端(尤其是 iOS WKWebView)根本不支持运行时修改 CSSStyleSheet 规则;Android 部分 WebView 表现不一致;即使插入成功,样式也不会触发重排重绘。错误写法如:document.styleSheets[0].insertRule('.btn { color: red }', 0) 在真机上基本是白忙一场。
- 小程序端对
insertRule完全无响应,基础库再高也不行 - H5 端虽部分支持,但无法保证变量作用域和优先级,容易被覆盖
- 所有动态换肤逻辑必须绕开 DOM 样式表操作,只动
:root上的属性值
setProperty 的正确调用时机和写法
必须等 DOM 可写、document.documentElement 存在后再执行,mounted 不够稳——尤其在 App 冷启动或小程序首次加载时。推荐在 onLaunch 或 onReady 后加 setTimeout(() => {}, 0)。
- 变量名严格区分大小写:
--primary-color和--PrimaryColor是两个变量 - 值必须是字符串类型:
setProperty('--bg', 0xffffff)会失败,得写'#ffffff' - 避免逐个设置:如果主题有 20 个变量,用
Object.keys(theme).forEach(k => ...)批量注入更安全 - 切换后务必调用
uni.setStorageSync('currentTheme', 'dark')持久化,否则冷启动回退默认
全局 CSS 变量在哪定义才真正生效
不能写在 App.vue 的 里,也不能塞进 uni.scss——后者是编译期静态替换,跟运行时无关。必须定义在非 scoped 的 块中,或单独引入 static/css/variables.css 并在 main.js 中 import。
- 小程序要求基础库 ≥ 2.7.0 才支持
var()运行时更新,低于此版本 fallback 到初始值 - 微信小程序里,
@keyframes和calc(--a + --b)不支持嵌套变量,要提前算好 - 别在条件编译块(如
// #ifdef MP-WEIXIN)里定义变量,CSS 变量不走条件编译逻辑
最容易被忽略的是:所有用到主题色的地方,都得显式写 color: var(--primary-color),而不是靠 SCSS 变量或写死值;否则改了 setProperty 也毫无反应。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











