- 示例工程
- 前端
- 移动开发
- 跨平台
【免费下载链接】uni-app
A cross-platform framework using Vue.js
本文以 uni-app x 官方主题适配文档为骨架,系统讲解light/dark暗黑模式适配的完整链路:从osTheme、hostTheme、appTheme三种主题概念的差异,到manifest.json、theme.json、pages.json的配置方式,再到「媒体查询」与「监听主题动态切换 class」两套适配方案,最后逐项拆解uni.setAppTheme、uni.onAppThemeChange等主题 API 的参数与行为。读完本文,你可以为自己的 uni-app x 项目落地「跟随系统」或「App 内独立切换」的暗黑主题能力,并理解底层 API 的触发时机与平台兼容差异。
主题体系基础概念:light 与 dark
iOS 13+、Android 10+系统级提供了暗黑模式/深色模式,系统之前的模式称为light(亮色),暗黑模式称为dark(深色)。低于上述版本的手机,系统层没有暗黑模式的概念,无法通过 API 获取或监听 OS 主题。
在 uni-app x 中,主题不是一个单一概念,而是分为3 种主题:OSTheme、hostTheme、appTheme。每种主题在不同平台的支持度不同,获取、设置和监听变化的方式也不同,其全貌如下表所示:
| 主题概念 | 描述 | App | Web | 小程序 | 获取方式 | 设置方式 | 监听变化 | | -- | -- | -- | -- | -- | -- | -- | -- | | osTheme | 手机 OS 的当前主题 | √ | x | x | uni.getDeviceInfo | - | uni.onOsThemeChange | | hostTheme | 浏览器或小程序宿主的当前主题 | x | √ | √ | uni.getAppBaseInfo | - | uni.onHostThemeChange | | appTheme | App 当前主题 | √ | X | x | uni.getAppBaseInfo | uni.setAppTheme | uni.onAppThemeChange |
注:获取主题除了上表列出的 API 外,也可以使用 uni.getSystemInfo(返回
osTheme、hostTheme、appTheme属性),uni.getDeviceInfo 与 uni.getAppBaseInfo 是更聚焦的取值入口。
Web 和小程序平台的注意点
- Web 和小程序没有能力获取 OS 的主题,只能获取浏览器或小程序宿主的主题,即
hostTheme。 - 可以选择不响应hostTheme(
darkmode设置为false),也可以根据 hostTheme调整自身的表现(darkmode设置为true)。 - 一旦在 manifest 里开启
darkmode,pages.json 的 tabbar、导航栏、页面背景色,以及某些浏览器或小程序自带的组件和涉及 UI 的 API,都会跟随 hostTheme 变化,开发者的应用无法控制这些 UI 的主题。例如浏览器的alert()、小程序的showModal。
appTheme 概念的用途
独立设置主题的场景常见于 App 平台,因此 App 平台新增了appTheme概念。appTheme 有几个用途:
- 独立于 osTheme 设置主题:App 可以有自己的主题,不强制跟随系统;
- 方便开发者和插件作者协作:推荐各个插件作者在涉及 UI 时支持主题适配,响应 App 的主题变化;
- uni-app x 框架自带的一些 UI 页面会响应 appTheme 变化,例如
showActionSheet、pages.json 的页面设置等。
先明确需求:三种适配做法
开发者做主题适配时,需要先明确自己的需求,以下 3 种做法需要做的事情完全不一样:
1. 只做 dark,不做 light
- 只需要在 pages.json 的
globalStyle里写死页面背景、tabBar 以及 navigationBar 的背景前景颜色; - 在 uvue 页面里写死暗色系颜色值,无需动态判断、无需 css 变量;
- 如果属于这种需求,本文接下来的内容都不用再看。
2. 只跟随「上家」(App 的上家是 osTheme,小程序和 web 的上家是 hostTheme),不需要给用户提供手动切换
- 需要做下面讲到的配置与监听,见后文。
3. App 上提供独立的 light/dark/auto 选项给用户,可以根据 osTheme,也可以独立设置
- 需要做更多事情,了解 appTheme 相关 API,见后文。
主题适配处理内容范围
开发者做主题适配时需处理的内容范围,涉及manifest.json、theme.json、pages.json、app.uvue,以及自己的 uvue 页面。下面依次说明。
1. manifest.json:开启 darkmode
Web 端、小程序需要配置 manifest.json 中web、mp-weixin根节点的"darkmode": true。配置后如果不生效请重新编译运行:
{ "mp-weixin": { "darkmode": true }, "web": { "darkmode": true } }本仓库的示例工程 src/manifest.json 正是这样配置的:mp-weixin节点下设置了"darkmode": true,web节点下同样设置了"darkmode": true,同时还开启了"uni-app-x": { "vapor": true, "styleIsolationVersion": "2" }(Vapor 蒸汽模式),这与下文「媒体查询适配」方案在新版 App 平台的能力直接相关。
2. pages.json 和 theme.json:全局样式的亮暗切换
pages.json 的亮黑设置,需要通过 theme.json 处理。
要特别注意:适配暗黑模式时,如果要适配 pages.json 中的 tabbar 和 NavigationBar,必须放置 theme.json 文件。
下面是 pages.json 中的globalStyle设置,在属性值中通过@来引用 theme.json 中定义的值:
"globalStyle": { "navigationBarTextStyle": "@navigationBarTextStyle", "navigationBarBackgroundColor": "@navigationBarBackgroundColor", "backgroundColor": "@backgroundColor", "backgroundTextStyle": "@backgroundTextStyle" },下面是 theme.json 的样例。theme.json 的位置放在pages.json 同级目录下(即项目根目录)。
在light和dark节点下,分别命名一批同名的变量,并分别赋值。这些变量可以在 pages.json 里直接引用:
{ "light": { "navigationBarTextStyle": "white", "navigationBarBackgroundColor": "#007AFF", "backgroundColor": "#efeff4", "tabBarPagebackgroundColorContent": "#efeff4", "backgroundTextStyle": "dark" }, "dark": { "navigationBarTextStyle": "white", "navigationBarBackgroundColor": "#1F1F1F", "backgroundColor": "#1F1F1F", "tabBarPagebackgroundColorContent": "#1F1F1F", "backgroundTextStyle": "light" } }完整的 theme.json 教程详见 theme.json。
几个关键约束:
- theme.json 里的变量仅能用于 pages.json,uvue 页面不能引用;
- 在 web 和小程序中,theme.json 的 dark 部分生效的前提是:
- manifest 设置了
darkmode: true; - 浏览器和小程序宿主(如微信)的主题外观是 dark;
- manifest 设置了
- 在 App 中,可以通过 manifest.json 的
app.defaultAppTheme配置应用默认主题,可取值为light、dark、auto,默认值为light。配置为auto时,appTheme 会跟随 OS 主题变化:
{ "app": { "defaultAppTheme": "auto" } }如果应用为用户提供主题切换功能,可以在运行时通过 uni.setAppTheme 设置light、dark或auto。
theme.json 为什么能避免「转场闪白 / 闪黑」:按照 themejson.md 的说明,在页面onLoad中设置页面样式会来不及——某些平台页面早于 onLoad 就可以创建并开始窗体转场动画,会导致动画刚开始的背景色、navigationBar 背景色与 onLoad 后不一致。theme.json 让新页面创建时第一时间就根据 pages.json 的设置初始化,从而避免闪白闪黑。
theme.json 变量支持的属性范围(来自 themejson.md):
- 全局配置
globalStyle与页面style支持:navigationBarBackgroundColor、navigationBarTextStyle、backgroundColor、backgroundTextStyle; - 全局配置
tabbar支持:color、selectedColor、backgroundColor、borderStyle、list(含iconPath、selectedIconPath)。
本仓库的示例工程 src/theme.json 就是一个完整的实战样例:在light节点下定义了navigationBarTextStyle: "white"、navigationBarBackgroundColor: "#007AFF"、backgroundColorContent: "#efeff4"、tabBarColor: "#7A7E83"、tabBarSelectedColor: "#007AFF"、tabBarBackgroundColor: "#F8F8F8"等变量;在dark节点下分别对应"#1F1F1F"、"#646464"、"#cacaca"、"#F8F8F8"等暗色取值,连 tabBar 的图标路径(tabBarComponentIconPath、tabBarAPIIconPath等)都做了亮暗双份定义。
完成上述基础配置后,页面和组件的主题样式可以根据平台及版本选择以下两种方案之一。
3. 使用媒体查询适配主题(推荐)
以下平台可以使用@media (prefers-color-scheme: light)和@media (prefers-color-scheme: dark)设置主题样式:
- Web 和小程序平台
- HBuilderX 5.25+ 的 App 平台蒸汽模式(Vapor 模式)
在支持上述能力的平台,推荐优先使用媒体查询适配主题。
媒体查询会根据hostTheme或appTheme自动匹配。主题变化时,匹配的样式也会自动更新,无需监听主题变化、维护响应式变量或动态切换 class。详见 @media 媒体查询。
页面只需要使用固定的 class,通过媒体查询分别定义亮色和暗色样式:
<template> <view class="page"> <text class="title">根据当前主题显示不同颜色的文字</text> </view> </template> <style> @media (prefers-color-scheme: light) { .page { --text-color: #333333; } } @media (prefers-color-scheme: dark) { .page { --text-color: #ffffff; } } .title { color: var(--text-color); } </style>媒体查询和 page 选择器,可以在app.uvue里使用,从而实现所有页面的效果批量控制。除非页面配置了禁止全局样式影响(样式隔离)。
如果 App 平台需要为用户提供light、dark、auto选项,直接调用uni.setAppTheme即可。appTheme 变化后,媒体查询会自动更新匹配的样式。
仓库佐证:本仓库的示例工程在 src/common/uni.css 以及多个页面(如 src/pages/tabBar/API.uvue、src/pages/component/text/text-props.uvue 等)中广泛使用@media (prefers-color-scheme: light/dark)定义亮暗样式,配合 src/App.uvue 在onLaunch中调用checkSystemTheme()完成主题初始化,是媒体查询方案在真实工程中的落地范本。
4. 监听主题并动态切换 class(老版兼容方案)
以下 App 平台场景,由于不支持媒体查询,只能通过 API 监听主题变化,然后动态切换 class:
- HBuilderX 5.25 之前的 App 平台
- App 平台 VDOM 模式
在已支持媒体查询的平台,如果业务逻辑还需要读取当前主题状态,可以另外使用主题 API 获取和监听,但样式仍可使用媒体查询,无需动态切换 class。
为了在同一套代码中兼容上述 App 平台场景,以下示例在各端统一使用动态 class。为避免每个页面都监听主题变化,可以在app.uvue中获取并监听主题,将结果存放在store/index.uts中,供各页面使用。
场景一:只跟随「上家」,不独立设置主题
如果应用只需要跟随上家,App 平台需要先将app.defaultAppTheme配置为auto,然后可以这样处理:
// app.uvue import { state } from '@/store/index.uts' onLaunch(() => { // #ifdef WEB || MP-WEIXIN state.isDark = (uni.getAppBaseInfo().hostTheme == 'dark') uni.onHostThemeChange((result) => { state.isDark = (result.hostTheme == 'dark') }) // #endif // #ifdef APP state.isDark = (uni.getDeviceInfo().osTheme == 'dark') uni.onOsThemeChange((result: OsThemeChangeResult) => { state.isDark = (result.osTheme == 'dark') }) // #endif })store/index.uts的内容如下:
type State = { // 是否为暗黑主题 isDark: boolean } export const state = reactive({ isDark: false } as State)场景二:App 允许用户独立设置主题
如果 App 平台允许用户独立设置主题,则需要获取和监听appTheme:
// app.uvue import { state } from '@/store/index.uts' onLaunch(() => { // #ifdef WEB || MP-WEIXIN state.isDark = (uni.getAppBaseInfo().hostTheme == 'dark') uni.onHostThemeChange((result) => { state.isDark = (result.hostTheme == 'dark') }) // #endif // #ifdef APP const appTheme = uni.getAppBaseInfo().appTheme state.isDark = appTheme == 'auto' ? uni.getDeviceInfo().osTheme == 'dark' : appTheme == 'dark' uni.onAppThemeChange((result: AppThemeChangeResult) => { state.isDark = (result.appTheme == 'dark') }) // #endif })注意:当appTheme为auto时,需要结合 osTheme 判断真实主题;当 appTheme 从auto切到具体值或跟随 OS 变化时,onAppThemeChange会在真实主题变化时触发(详见下文 API 版本历史说明)。
可以在app.uvue的全局样式中定义亮色和暗色 class。除非页面或组件的样式隔离策略禁止全局样式影响,否则页面可以直接使用这些 class:
.theme-light { --text-color: #333333; } .theme-dark { --text-color: #ffffff; }页面根节点根据state.isDark动态切换 class:
<template> <view :class="state.isDark ? 'theme-dark' : 'theme-light'"> <text class="title">根据当前主题显示不同颜色的文字</text> </view> </template> <script setup lang="uts"> import { state } from '@/store/index.uts' </script> <style> .title { color: var(--text-color); } </style>性能与体验提醒:动态切换 class 由于要执行 script,性能没有媒体查询高。另外动态切换 class 的代码与 theme.json 的执行可能不在同一帧,会造成 theme.json 先生效、class 后生效,有闪烁感。推荐升级到 HBuilderX 5.25 的蒸汽模式,使用媒体查询方案适配主题。
仓库佐证:本仓库 src/store/index.uts 中定义了全局响应式状态state.isDarkMode,并封装了checkSystemTheme()函数:Web / 微信小程序端通过uni.getAppBaseInfo().hostTheme初始化并uni.onHostThemeChange监听宿主主题;App 端通过uni.getSystemInfo结合appTheme与osTheme判断真实主题,并用uni.onAppThemeChange持续监听(见 src/store/index.uts)。而 src/App.uvue 在onLaunch里调用checkSystemTheme(),正是把「主题监听集中在应用入口、全局状态供所有页面共享」这一模式的真实实现。
内置组件和 UI 相关 API 的适配说明
uni-app x 的App 和 Web 平台框架中自带的界面,均已适配暗黑模式(小程序平台由小程序宿主自行适配),目前包括:
uni.showActionSheet(HBuilderX 4.51+)uni.showModal(HBuilderX 4.61+)uni.chooseLocation(HBuilderX 4.33+)uni.openLocation(HBuilderX 4.41+)uni.chooseImage/chooseVideo/chooseMedia/chooseFile:当调用系统的选择界面时,该界面的主题跟随osTheme,应用层无法干预
另外,uni-app x 的内置组件在 App 和 Web 平台均支持 css 设置所有样式,这样就可以在所有样式控制中使用 css 变量;但小程序平台的内置组件依赖其自身实现,有的组件需要通过属性控制样式,此时无法使用 css 变量。
主题 API 详解
以下 API 的源码实现位于独立的 uni-theme 模块(uni_modules/uni-theme),行为说明以本文为准。
uni.setAppTheme(options)
设置应用主题。
uni.setAppTheme用于设置 App 当前主题。开发者仍需为不同主题定义相应的页面和组件样式。它的作用是:
- 根据 theme.json,设置 pages.json 的亮/暗主题;
- HBuilderX 5.25+,在 App 平台蒸汽模式下,自动更新
@media (prefers-color-scheme: light)和@media (prefers-color-scheme: dark)匹配的样式; - 触发
uni.onAppThemeChange,开发者和组件作者均可监听这个事件,自行响应将页面设置为对应的亮/暗风格。
当然组件作者也可以不监听onAppThemeChange,而是暴露主题切换 API 给开发者,由开发者监听主题切换,再调用组件的主题切换 API。
uni-app x 的 UI 相关 API(比如showModal),也会响应setAppTheme。
兼容性:
| Web | 微信小程序 | Android | iOS | HarmonyOS | | :- | :- | :- | :- | :- | | x | x | 4.18 | 4.18 | 4.71 |
参数:
| 名称 | 类型 | 必填 | 兼容性 | | :- | :- | :- | :-: | | options |SetAppThemeOptions| 是 | Web: x; 微信小程序: x; Android: 4.18; iOS: 4.18; HarmonyOS: 4.71 |
options 的属性描述:
| 名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 | | :- | :- | :- | :- | :-: | :- | | theme | string | 是 | | Web: x; 微信小程序: x; Android: 4.18; iOS: 4.18; HarmonyOS: 4.71 | 主题 | | success | (result: SetAppThemeSuccessResult) => void | 否 | null | Web: x; 微信小程序: x; Android: 4.18; iOS: 4.18; HarmonyOS: 4.71 | 接口调用成功的回调函数 | | fail | (result: AppThemeFail) => void | 否 | null | Web: x; 微信小程序: x; Android: 4.18; iOS: 4.18; HarmonyOS: 4.71 | 接口调用失败的回调函数 | | complete | (result: any) => void | 否 | null | Web: x; 微信小程序: x; Android: 4.18; iOS: 4.18; HarmonyOS: 4.71 | 接口调用结束的回调函数(调用成功、失败都会执行) |
theme 的属性描述:
| 合法值 | 兼容性 | 描述 | | :- | :-: | :- | | light | Web: x; 微信小程序: x | 亮色模式 | | dark | Web: x; 微信小程序: x | 深色模式 | | auto | Web: x; 微信小程序: x | 跟随系统模式 |
SetAppThemeSuccessResult 的属性值:
| 名称 | 类型 | 必备 | 兼容性 | | :- | :- | :- | :-: | | theme | string | 是 | Web: x; 微信小程序: x |
AppThemeFail 的属性值:
| 名称 | 类型 | 必备 | 兼容性 | 描述 | | :- | :- | :- | :-: | :- | | errCode | number | 是 | Web: x; 微信小程序: x; Android: 4.18; iOS: 4.18; HarmonyOS: 4.71 | 错误码(702001 参数错误;2002000 未知错误) | | errSubject | string | 是 | Web: x; 微信小程序: x | 统一错误主题(模块)名称 | | data | any | 否 | Web: x; 微信小程序: x | 错误信息中包含的数据 | | cause | Error | 否 | | 源错误信息,可以包含多个错误,详见 SourceError | | errMsg | string | 是 | Web: x; 微信小程序: x | |
errCode 合法值:702001(参数错误)、2002000(未知错误)。
示例:
uni.setAppTheme({ theme: "auto", success: function() { console.log("设置appTheme为 auto 成功") }, fail: function(e: IAppThemeFail) { console.log("设置appTheme为 auto 失败,原因:", e.errMsg) } })uni.onAppThemeChange / uni.offAppThemeChange
开启 / 取消监听应用主题变化。
版本历史调整(重要,涉及回调语义):
- HBuilderX 4.18 版本:
uni.setAppTheme设置的 theme 值变化时触发本监听回调,回调参数中的appTheme值可能是"light" | "dark" | "auto"。在 app 平台设置应用的 theme 值为auto后,需再次查询 osTheme 来判断当前的真实主题;如果应用主题是auto,那么需要同时监听 osTheme 的变化。 - HBuilderX 4.19 版本起:应用的light/dark 主题真正发生变化时才触发监听回调。无论是手动设置 setAppTheme 还是跟随 osTheme 变化,只要真正变化了就会触发本监听。回调参数中的
appTheme值只能是"light" | "dark"。
onAppThemeChange 兼容性:
| Web | 微信小程序 | Android | iOS | HarmonyOS | | :- | :- | :- | :- | :- | | x | x | 4.18 | 4.18 | 4.71 |
参数:callback: (res: AppThemeChangeResult) => void,必填。
AppThemeChangeResult 的属性值:
| 名称 | 类型 | 必备 | 兼容性 | 描述 | | :- | :- | :- | :-: | :- | | appTheme | string | 是 | Web: x; 微信小程序: x; Android: 4.18; iOS: 4.18; HarmonyOS: 4.71 | 应用主题 |
appTheme 合法值:light(亮色模式)、dark(深色模式)。
返回值:number(callbackId,用于注销监听)。
示例:
//callbackId 用于注销监听 val callbackId = uni.onAppThemeChange((res: AppThemeChangeResult) => { console.log("onAppThemeChange", res.appTheme) })val callbackId = uni.onAppThemeChange((res: AppThemeChangeResult) => { console.log("onAppThemeChange", res.appTheme) }) //... //... //注销监听 uni.offAppThemeChange(this.appThemeChangeId)offAppThemeChange兼容性:Web: x、Android: 4.18、iOS: 4.18、HarmonyOS: 4.71;参数id: number必填。
uni.onOsThemeChange / uni.offOsThemeChange
开启 / 取消监听系统主题变化。
onOsThemeChange 兼容性:
| Web | 微信小程序 | Android | iOS | HarmonyOS | | :- | :- | :- | :- | :- | | x | x | 4.18 | 4.18 | 4.71 |
参数:callback: (res: OsThemeChangeResult) => void,必填。
OsThemeChangeResult 的属性值:
| 名称 | 类型 | 必备 | 兼容性 | 描述 | | :- | :- | :- | :-: | :- | | osTheme | string | 是 | Web: x; 微信小程序: x; Android: 4.18; iOS: 4.18; HarmonyOS: 4.71 | 系统主题 |
osTheme 合法值:light(亮色模式)、dark(深色模式)。
返回值:number(callbackId,用于注销监听)。
示例:
//callbackId 用于注销监听 val callbackId = uni.onOsThemeChange((res: OsThemeChangeResult)=> { console.log("onOsThemeChange---", res.osTheme) })val callbackId = uni.onOsThemeChange((res: OsThemeChangeResult)=> { console.log("onOsThemeChange---", res.osTheme) }) ... ... //注销监听 uni.offOsThemeChange(callbackId)特别注意:
- Android 10、iOS 13 才开始支持深色模式主题
dark,更低版本无法获取、监听 OS 的主题; - iOS 平台应用在进入后台时,会分别截取 app 在 light 和 dark 模式下的截图,用于系统主题切换的同时对后台 app 预览视图进行切换,所以会切换多次 light/dark 模式。程序正常响应 change 事件即可,否则系统截取的图片可能会出现异常;如果确实有必要忽略这种情况下的 change 事件,可以在
onHide后自行忽略。
uni.onHostThemeChange / uni.offHostThemeChange
监听 / 取消监听宿主(浏览器或小程序宿主)主题状态变化。
onHostThemeChange 兼容性:
| Web | 微信小程序 | Android | iOS | HarmonyOS | | :- | :- | :- | :- | :- | | 4.35 | 4.41 | x | x | 4.71 |
参数:callback: (result: OnHostThemeChangeCallbackResult) => void,必填。
OnHostThemeChangeCallbackResult 的属性值:
| 名称 | 类型 | 必备 | 兼容性 | 描述 | | :- | :- | :- | :-: | :- | | hostTheme | string | 是 | Android: x; iOS: x | 主题名称 |
hostTheme 合法值:light(亮色模式)、dark(深色模式)。
返回值:number(callbackId,用于注销监听)。
offHostThemeChange兼容性同为 Web: 4.35、微信小程序: 4.41、HarmonyOS: 4.71;参数id: number必填。
已废弃 API:uni.onThemeChange / uni.offThemeChange
已废弃,在 web、小程序上推荐使用onHostThemeChange/offHostThemeChange替代:
uni.onThemeChange(callback):监听系统主题状态变化,兼容性 Web: 4.0、微信小程序: 4.41、HarmonyOS: 4.71;回调参数OnThemeChangeCallbackResult.theme合法值为light/dark。uni.offThemeChange(callback):取消监听系统主题状态变化,兼容性同上。
完整示例:theme-change 页面与自动化测试
本仓库的示例工程在 src/pages/API/theme-change/theme-change.uvue 中提供了完整可运行的主题切换页面,其核心逻辑完整覆盖了上述 API 的典型用法:
bindOsThemeChange():App 端通过uni.onOsThemeChange注册系统主题监听,回调中更新osTheme;bindAppThemeChange():App 端用uni.onAppThemeChange监听应用主题;Web / 小程序端用uni.onHostThemeChange监听宿主主题,两端通过条件编译共用同一页面;setAppTheme(value):调用uni.setAppTheme({ theme }),success/fail回调中打印结果;onReady:通过uni.getSystemInfo读取osTheme、appTheme、hostTheme初始化展示数据(App 端对appTheme == 'auto'的情况结合osTheme换算真实主题),随后注册监听;onUnload:分别调用uni.offAppThemeChange、uni.offOsThemeChange、uni.offHostThemeChange注销监听,避免页面销毁后回调泄漏;- 页面提供
light/dark/auto三个 radio 选项,通过radioChange触发setAppTheme。
与之配套的自动化测试 src/pages/API/theme-change/theme-change.test.js 验证了 setAppTheme 的行为链路:
it("check-set-app-theme", async () => { await page.callMethod('setAppTheme', "dark") await page.waitFor(300) expect(await page.data('appTheme')).toBe("dark") const image = await program.screenshot({ deviceShot: true }); expect(image).toSaveImageSnapshot(); })测试先通过program.reLaunch进入/pages/API/theme-change/theme-change页面并读取originalTheme,随后调用页面暴露的setAppTheme('dark'),断言appTheme状态变为dark并截图比对,最后在afterAll中恢复原始主题——这也从工程角度印证了「setAppTheme → onAppThemeChange 回调 → 页面状态更新」的完整调用链。
示例项目参考
- hello uni-app x 示例目前使用媒体查询适配主题:其
app.uvue、页面和组件样式中使用@media (prefers-color-scheme: light)和@media (prefers-color-scheme: dark)定义不同主题下的样式(本仓库 src/common/uni.css 及各页面样式即为该方案的实例),pages/CSS/prefers-color-scheme页面提供了完整示例。 - test-theme 是一个基于无媒体查询、动态切换 class的示例项目,演示主题设置,适合需要兼容 HBuilderX 5.25 之前 App 平台或 VDOM 模式的场景。
总结:如何选择适配方案
| 需求 | 推荐方案 | 需要做的事 | | :- | :- | :- | | 只做 dark | 写死颜色 | 仅配置 pages.json 的 globalStyle,无需任何监听 | | 只跟随系统(web/小程序) | 媒体查询 + manifest darkmode |web/mp-weixin节点开启darkmode: true,样式用@media (prefers-color-scheme)| | 只跟随系统(App) | 媒体查询(5.25+ 蒸汽模式)或监听 osTheme |app.defaultAppTheme设为auto,结合uni.onOsThemeChange判断真实主题 | | App 独立切换 light/dark/auto |uni.setAppTheme+ 媒体查询(或监听 appTheme) | 配置theme.json,用setAppTheme切换,onAppThemeChange驱动业务逻辑 |
核心要点回顾:theme.json负责 pages.json 全局样式的亮暗切换,媒体查询负责 uvue 页面样式的自动匹配,setAppTheme/onAppThemeChange负责 App 独立主题的运行时控制;在 HBuilderX 5.25+ 蒸汽模式下优先使用媒体查询方案,可获得无闪烁、无 JS 开销的最优体验。
- 示例工程
- 前端
- 移动开发
- 跨平台
【免费下载链接】uni-app
A cross-platform framework using Vue.js
相关推荐
uni-app x 主题适配实战:theme.json 配置详解与暗黑模式 pages.json 样式控制
uni app x 主题适配实战:theme.json 配置详解与暗黑模式 pages.json 样式控制 本文面向使用 uni app x 开发 App(An
示例工程前端移动开发跨平台uni-app暗黑模式:多主题适配方案终极指南
uni app暗黑模式:多主题适配方案终极指南 在当今移动应用开发中, uni app暗黑模式 已成为提升用户体验的重要功能。作为使用Vue.js的跨平台框架,
示例工程前端移动开发跨平台RuView WiFi-DensePose 边缘智能核心模块完全指南:ESP32 上运行的手势识别、入侵检测与 RVF 容器
RuView WiFi DensePose 边缘智能核心模块完全指南:ESP32 上运行的手势识别、入侵检测与 RVF 容器 本文档面向在 RuView / W
示例工程前端移动开发跨平台
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考