App端夜间模式需手动监听系统主题并强制刷新根节点类名,因原生容器不透出变更事件;须在manifest.json中配置"darkmode":true,用uni.onThemeChange监听并在App.vue中设置全局状态和根元素class。

App端夜间模式不能只靠 prefers-color-scheme 媒体查询自动生效——iOS和Android原生容器不透出系统主题变更事件,必须手动监听 + 强制刷新根节点类名。
App端无法自动响应系统深色切换?用 uni.onThemeChange 监听
微信小程序有 onThemeChange 回调,但 App 端(iOS/Android)在 HBuilderX 4.76+ 才正式支持该 API。旧版本或未开启 darkmode 配置时,这个监听器根本不会触发。
- 必须先在
manifest.json的app-plus节点里显式配置"darkmode": true,否则uni.onThemeChange不注册 - 监听写法要放在
App.vue的onLaunch或onShow里,不能只写在页面级生命周期中 - 回调返回的
theme值只有"light"或"dark",不是字符串拼接或布尔值 - 拿到值后,**必须主动设置全局状态并重设根元素 class**,不能只存变量——App端不会自动 re-render 样式
全局 CSS 变量怎么定义才真正生效?别只写 :root
很多开发者把变量全塞进 :root,结果 App 端暗黑模式下变量没更新。因为 App 容器默认不识别 [data-theme="dark"] 这类属性选择器,也不支持 @media (prefers-color-scheme: dark) 动态匹配。
- 推荐写法是:给
根容器加动态 class,比如:class="theme === 'dark' ? 'theme-dark' : ''" - 然后在
uni.scss或App.vue中分别定义:
:root {
--bg: #ffffff;
--text: #333333;
}
.theme-dark {
--bg: #1a1a1a;
--text: #e6e6e6;
}
- 所有组件内必须用
var(--bg),不能写死#ffffff;且不要依赖!important覆盖,那会破坏变量链路 - Nvue 页面需额外加
:key="theme"强制重绘,否则 class 切换后样式不更新
pages.json 里的主题变量为什么没生效?检查 themeLocation 路径和 key 名
pages.json 中写的 @navBgColor 这类变量,实际取值完全依赖 theme.json 文件结构和 manifest.json 中的 themeLocation 配置。路径错一位、key 名大小写不对,都会回退成默认值。
-
themeLocation是相对项目根目录的路径,比如写"theme.json"就必须确保文件真正在根目录,而不是src/theme.json -
theme.json中的 key 必须严格对应 pages.json 引用名,例如"navBgColor"不能写成"nav-bg-color"或"navigationBarBackgroundColor" - 仅
pages.json支持这种变量语法,组件内 style 或 class 里不能用@xxx - App 端的导航栏背景、文字色等,优先级顺序是:
自定义 color / background-color 属性>theme.json 变量>默认值
uni-ui 组件不响应夜间模式?得手动 patch 内联样式
uni-ui 所有组件(如 uni-list、uni-numbox)大量使用内联 style,CSS 变量无法穿透。媒体查询在 App 端也基本失效,所以不能指望 @media (prefers-color-scheme: dark) 自动覆盖。
- 最稳方案:在
uni_modules/uni-xxx/components/uni-xxx/uni-xxx.vue的里,直接写两套规则:
.uni-list--border {
border-bottom-color: #eee;
}
.theme-dark .uni-list--border {
border-bottom-color: #333 !important;
}
- 如果不想改源码,可在页面级用
::v-deep(Vue 2)或:deep(Vue 3)局部覆盖,但仅对当前页面有效 - 注意:Nvue 页面不支持
::v-deep,必须改组件源码或用 class + CSS 变量重写逻辑
真正麻烦的不是切换逻辑,而是每处内联样式都要人工校验是否被变量接管——图片、图标、渐变、阴影这些容易被忽略,上线后才发现按钮看不见、文字糊成一片。











