HarmonyOS鸿蒙Next中uniapp适配深色模式怎么操作?

HarmonyOS鸿蒙Next中uniapp适配深色模式怎么操作? 【问题描述】uniapp鸿蒙适配深色模式怎么操作?按照文档https://ask.dcloud.net.cn/article/42222中的方法每个地方都要顾及到太麻烦了,有没有更简便的替代方案?

【问题现象】无。

【版本信息】不涉及。

【复现代码】demo太大,无法上传。

【尝试的解决方案】无。

7 回复

开发者您好,uni-app在非HarmonyOS平台可在manifest.json -> app-plus配置darkmode:true深色模式,见DarkMode适配指南

/* 5+App特有相关 */
"app-plus" : {
    "darkmode" : true,
    "usingComponents" : true,
    "nvueStyleCompiler" : "uni-app",
    "compilerVersion" : 3,
    "splashscreen" : {
        "alwaysShowBeforeRender" : true,
        "waiting" : true,
        "autoclose" : true,
        "delay" : 0
    },
    /* 模块配置 */
    "modules" : {},
    /* 应用发布信息 */
    "distribute" : {
        /* android打包配置 */
        "android" : {},
        /* ios打包配置 */
        "ios" : {},
        /* SDK配置 */
        "sdkConfigs" : {}
    }
},

HarmonyOS开发中不会读取app-plus下配置的选项,在app-harmony节点下可以设置HarmonyOS参数。uni-app在HarmonyOS平台上设置深色模式的步骤如下:

  1. 在manifest.json中开启深色模式。

    "app-harmony" : {
        "darkmode": true,
    }
    
  2. 在App.vue的style标签下,通过媒体查询定义深色模式样式,示例代码如下:

    <style type="text/css">
      @media (prefers-color-scheme: dark) {
        .contentCss{ background:  #000000; color: white; }
        .hrefCss{ color: #317AF7; }
      }
    </style>
    

更多关于HarmonyOS鸿蒙Next中uniapp适配深色模式怎么操作?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


一、核心简化思路(仅 HarmonyOS Next)

针对 HarmonyOS Next 纯原生模式,无需逐个页面 / 组件修改样式,核心方案是:全局 CSS 变量统一管理浅色 / 深色样式 + 自动监听系统主题切换,仅需定义一次全局样式规则,所有页面 / 组件自动继承,彻底避免 “逐个顾及” 的麻烦。

二、最简实现步骤(仅 HarmonyOS Next)

步骤 1:全局定义主题 CSS 变量(核心,仅需写一次)

App.vue<style>中定义浅色 / 深色模式的全局 CSS 变量,覆盖所有通用样式(背景、文字、边框、按钮等),所有页面 / 组件直接使用变量,无需单独写样式。

vue

<!-- App.vue -->
<template>
  <view>
    <router-view />
  </view>
</template>

<script>
export default {
  onLaunch() {
    // 初始化主题(页面加载时同步系统主题)
    this.initTheme();
    // 监听系统主题切换(HarmonyOS Next)
    this.watchThemeChange();
  },
  methods: {
    // 初始化主题:获取系统当前主题并设置
    initTheme() {
      const systemInfo = uni.getSystemInfoSync();
      // HarmonyOS Next中,systemInfo.theme返回'dark'/'light'
      const theme = systemInfo.theme || 'light';
      document.documentElement.setAttribute('data-theme', theme);
    },
    // 监听主题切换(HarmonyOS Next系统级监听)
    watchThemeChange() {
      // UniApp跨端API:监听系统主题变化
      uni.onThemeChange((res) => {
        document.documentElement.setAttribute('data-theme', res.theme);
      });
    }
  }
};
</script>

<style lang="scss">
/* 全局样式重置(可选) */
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* 1. 浅色模式(默认) */
:root {
  --bg-color: #ffffff;       // 全局背景
  --text-color: #333333;     // 主文字
  --sub-text-color: #666666; // 次要文字
  --border-color: #eeeeee;   // 边框
  --button-bg: #007aff;      // 按钮背景
  --button-text: #ffffff;    // 按钮文字
}

/* 2. 深色模式(HarmonyOS Next) */
:root[data-theme="dark"] {
  --bg-color: #1a1a1a;       // 深色背景
  --text-color: #f5f5f5;     // 深色文字
  --sub-text-color: #cccccc; // 深色次要文字
  --border-color: #333333;   // 深色边框
  --button-bg: #0056d2;      // 深色按钮背景
  --button-text: #ffffff;    // 深色按钮文字
}

/* 全局通用样式:直接使用变量,所有页面继承 */
page {
  background-color: var(--bg-color);
  color: var(--text-color);
  min-height: 100vh;
}

/* 通用按钮样式(全局生效) */
.btn {
  background-color: var(--button-bg);
  color: var(--button-text);
  border: 1px solid var(--border-color);
  border-radius: 8rpx;
  padding: 20rpx 40rpx;
}

/* 通用文本样式 */
.text-sub {
  color: var(--sub-text-color);
}
</style>

步骤 2:页面 / 组件直接使用全局变量(零额外修改)

所有页面 / 组件无需写深色模式逻辑,直接使用App.vue定义的 CSS 变量,自动跟随系统主题切换:

vue

<!-- 任意页面(如index.vue) -->
<template>
  <view class="page-container">
    <text class="title">鸿蒙深色模式测试</text>
    <text class="text-sub">自动适配系统主题</text>
    <button class="btn" type="default">通用按钮</button>
  </view>
</template>

<style scoped>
/* 页面专属样式:仅补充个性化,仍用全局变量 */
.page-container {
  padding: 40rpx;
  border-bottom: 1px solid var(--border-color);
}

.title {
  font-size: 36rpx;
  color: var(--text-color); // 直接用全局变量
  margin-bottom: 20rpx;
}
</style>

步骤 3:HarmonyOS Next 原生配置增强(可选,优化体验)

如需让鸿蒙原生层(如状态栏、窗口背景)也适配深色模式,在native/ohos/module.json5中配置主题支持:

json

{
  "$schema": "https://developer.harmonyos.com/cn/schemas/ohos/module.json5/v3",
  "module": {
    "abilities": [
      {
        "name": "MainAbility",
        // 配置深色模式支持
        "colorMode": "auto", // 自动跟随系统主题(light/dark/auto)
        "window": {
          "backgroundColor": "#00000000", // 透明,跟随页面CSS
          "navigationBarColor": "auto",   // 导航栏自动适配主题
          "statusBarColor": "auto"        // 状态栏自动适配主题
        }
      }
    ]
  }
}

三、进阶优化(可选,针对特殊场景)

1. 图片 / 图标适配(无需多套图片)

用 CSS 变量控制背景图,或使用 SVG / 字体图标(自动继承颜色):

css

/* 图标适配:SVG/字体图标直接继承文字颜色 */
.icon {
  font-family: "iconfont";
  color: var(--text-color);
  font-size: 40rpx;
}

/* 背景图适配:通过变量切换 */
.bg-img {
  background-image: var(--bg-img);
}
:root { --bg-img: url('/static/bg-light.png'); }
:root[data-theme="dark"] { --bg-img: url('/static/bg-dark.png'); }

2. 鸿蒙原生组件适配(少量特殊组件)

若使用鸿蒙原生组件(如ohos-map),通过条件编译 + 变量适配:

vue

<template>
  <!-- 鸿蒙原生组件仅在HarmonyOS Next生效 -->
  <view v-if="isHarmonyNext">
    <ohos-map :style="{background: var(--bg-color)}"></ohos-map>
  </view>
</template>

<script>
export default {
  data() {
    return {
      isHarmonyNext: uni.getSystemInfoSync().osName === 'harmonyos'
    };
  }
};
</script>

四、对比官方方案的核心优势

官方方案(逐个修改) 本方案(全局变量 + 自动切换)
每个页面 / 组件写两套样式 仅在 App.vue 定义一次全局变量
需手动监听每个页面主题 全局监听,自动同步所有页面
原生层需单独配置 原生层仅需一次配置
维护成本高(改一处需改所有) 维护成本低(仅改全局变量)

五、HarmonyOS Next 专属注意事项

  1. 主题监听兼容性:UniApp 的uni.onThemeChange在 HarmonyOS Next 中已原生支持,无需额外原生代码;
  2. 避免内联样式:内联样式(如style="color: #333")不会继承 CSS 变量,尽量用 class;
  3. 性能优化:全局 CSS 变量是浏览器原生特性,HarmonyOS Next 中无性能损耗,比 JS 动态修改样式更高效;
  4. 隐私 / 权限:适配深色模式无需申请权限,仅需跟随系统主题即可。

六、相关文档(精准参考)

  1. UniApp 主题切换 API:跨端主题监听;
  2. HarmonyOS Next 深色模式配置:原生层主题配置;
  3. CSS 变量官方文档:全局变量使用规范。

总结

适配 HarmonyOS Next 深色模式的最简路径:全局 CSS 变量定义样式 + 自动监听系统主题切换,仅需在App.vue中写一次全局样式和监听逻辑,所有页面 / 组件直接使用变量,无需逐个修改,彻底解决 “每个地方都要顾及” 的痛点。

在项目resources目录下创建dark子目录,存放深色模式专用的颜色和图片资源。

  • base/element/color.json定义浅色配色
  • dark/element/color.json定义深色配色(同名不同值)

推荐使用鸿蒙系统预置资源,实现自动切换效果:

/* 直接调用系统文本主色 */
.text-primary {
  color: $r('sys.color.ohos_id_color_text_primary');
}

 媒体查询监听 在全局CSS中通过媒体查询响应系统模式:

@media (prefers-color-scheme: dark) {
  :root {
    --bg-color: #1a1a1a;
    --text-color: #ffffff;
  }
}

在页面逻辑中获取系统主题状态:

uni.getSystemInfo({
  success: function(res) {
    const isDark = res.theme === 'dark';
    this.setData({ isDarkMode: isDark });
  }
});

找HarmonyOS工作还需要会Flutter的哦,有需要Flutter教程的可以学学大地老师的教程,很不错,B站免费学的哦:https://www.bilibili.com/video/BV1S4411E7LY/?p=17

方案一:CSS变量 + 媒体查询 这是最简洁的方法,不需要每个地方都手动配置:

  1. 创建全局样式文件 theme.scss:
:root {
  // 浅色模式
  --bg-color: #ffffff;
  --text-color: #333333;
  --card-bg: #f5f5f5;
  --border-color: #e0e0e0;
}

@media (prefers-color-scheme: dark) {
  :root {
    // 深色模式
    --bg-color: #1a1a1a;
    --text-color: #ffffff;
    --card-bg: #2a2a2a;
    --border-color: #3a3a3a;
  }
}
  1. 在 App.vue 中引入:
@import "@/theme.scss";
  1. 页面中直接使用变量:
.container {
  background-color: var(--bg-color);
  color: var(--text-color);
}

方案二:使用uni-app-config自动化配置工具 可以使用自动化配置插件来简化重复工作:

yarn add uniapp-config --dev

这个工具可以:

  • 自动修改 manifest.json 配置
  • 自动修改 pages.json
  • 自动切换主题配置
  • 避免手动修改多个文件

方案三:系统预置颜色资源 对于鸿蒙原生开发,可以直接使用系统预置的动态颜色:

/* 使用系统级动态颜色,自动适配深色模式 */
.text-primary {
  color: $r('sys.color.ohos_id_color_text_primary');
}

.bg-background {
  background-color: $r('sys.color.ohos_id_color_background');
}

方案四:简化版配置(最少改动) 如果你只需要基本的深色模式支持,可以只做这些配置:

  1. 在 manifest.json 中开启:
{
  "app-harmony": {
    "darkmode": true
  }
}
  1. 在 App.vue 中添加媒体查询:
@media (prefers-color-scheme: dark) {
  page {
    background-color: #1a1a1a;
    color: #ffffff;
  }
}

组合方案:

  1. 使用 CSS变量 + 媒体查询 处理页面样式
  2. 只做必要的 manifest.json 配置
  3. 避免使用复杂的 theme.json 配置

这样只需要:

  • 一个 theme.scss 文件
  • 一行 manifest.json 配置
  • 页面中使用 CSS 变量

就能实现完整的深色模式适配

在HarmonyOS鸿蒙Next中适配UniApp深色模式,需使用ArkTS/ArkUI开发。通过@ohos.app.ability.Configuration模块获取系统主题,监听configurationChange事件。使用getSystemColorMode()判断当前模式,结合条件渲染或资源替换实现界面切换。UniApp需调用鸿蒙原生能力接口,具体可参考华为官方ArkTS API文档中UI适配相关章节。

在HarmonyOS Next中,uniapp适配深色模式确实有更高效的方案,无需在每个组件或页面手动处理。

核心方案是利用HarmonyOS Next的系统主题API与uniapp的CSS变量能力进行联动。具体操作如下:

  1. 获取系统主题:在应用入口或全局逻辑中,使用HarmonyOS Next的@ohos.app.ability.Configuration模块监听系统主题变化。可以获取到当前的colorMode(例如COLOR_MODE_LIGHTCOLOR_MODE_DARK)。

  2. 定义CSS变量:在uniapp的全局CSS(如App.vuestyle中)或单独CSS文件中,定义两套CSS变量,分别对应浅色和深色主题。例如:

    :root {
      --bg-color: #ffffff;
      --text-color: #000000;
      /* 其他设计变量 */
    }
    @media (prefers-color-scheme: dark) {
      :root {
        --bg-color: #1a1a1a;
        --text-color: #f0f0f0;
      }
    }
    

    注意:HarmonyOS Next会注入prefers-color-scheme媒体查询,因此可以通过CSS媒体查询直接响应系统主题。

  3. 应用CSS变量:在vue页面的样式中,直接使用这些CSS变量,而不是固定的颜色值。例如:

    .container {
      background-color: var(--bg-color);
      color: var(--text-color);
    }
    
  4. 动态切换(可选):如果应用需要支持独立于系统的主题切换,可以在获取系统主题后,将主题状态存储在全局状态管理(如Vuex或Pinia)中。然后通过动态修改HTML元素的data-theme属性或类名,并配合预先定义好的两套CSS变量来实现覆盖。

优势

  • 关注点分离:颜色定义集中在CSS变量中,业务代码只需引用变量。
  • 维护简单:只需修改CSS变量值即可统一调整主题。
  • 性能良好:利用CSS和系统原生接口,切换流畅。

注意事项

  • 确保uniapp for HarmonyOS Next的版本支持CSS变量和相关的媒体查询。
  • 对于图片等资源,可能需要准备深浅两套,并通过条件渲染或CSS背景图变量进行切换。

此方案避免了手动逐处修改样式,通过CSS变量与系统主题的绑定实现高效、统一的深色模式适配。

回到顶部