什么是暗黑模式
暗黑模式(Dark Mode),也被称为夜间模式或深色模式,是一种使用深色背景和浅色文字的界面显示模式。
主要特点
- 护眼体验: 在光线较暗的环境下减少眼部疲劳
- 节省电量: 在 OLED 屏幕设备上能够显著节省电池消耗
- 视觉美观: 提供现代化的视觉体验和专业感
使用指南
本章节将介绍在 uni-app 项目中实现h5和微信小程序的暗黑模式功能的方案。你可以结合本文内容并参考 uni-app 官方的 DarkMode 适配指南 来完成适配。
适配组成
暗黑模式的完整适配包含以下几个核心部分:
uni-app 平台配置
uni-app 提供了官方的暗黑模式配置方案,通过 manifest.json 和 theme.json 实现平台级的主题支持,其指南已经比较详细,本章节将简单介绍一下,具体可以参考官方文档。
📖 详细文档 : uni-app 暗黑模式适配指南
配置步骤
在 manifest.config.ts 中开启暗黑模式
// H5 配置
"h5": {
"darkmode": true,
"themeLocation": "theme.json"
}
// 微信小程序配置
"mp-weixin": {
"darkmode": true,
"themeLocation": "theme.json"
}
创建 theme.json 主题变量文件
{
"light": {
"bgColor": "#F8F8F8",
"bgColorBottom": "#F8F8F8",
"bgColorTop": "#F8F8F8",
"bgTxtStyle": "dark",
"navBgColor": "#FFF",
"navTxtStyle": "black",
"tabBgColor": "#ffffff",
"tabBorderStyle": "black",
"tabColor": "#bfbfbf",
"tabSelectedColor": "#0165FF"
},
"dark": {
"bgColor": "#000",
"bgColorBottom": "#000",
"bgColorTop": "#000",
"bgTxtStyle": "light",
"navBgColor": "#000000",
"navTxtStyle": "white",
"tabBgColor": "#1a1a1a",
"tabBorderStyle": "white",
"tabColor": "#bfbfbf",
"tabSelectedColor": "#0165FF"
}
}
在 pages.config.ts 中引用主题变量
{
"globalStyle": {
// 导航栏配置
navigationBarBackgroundColor: '@navBgColor',
navigationBarTextStyle: '@navTxtStyle',
navigationBarTitleText: 'Wot Starter',
// 页面背景配置
backgroundColor: '@bgColor',
backgroundTextStyle: '@bgTxtStyle',
backgroundColorTop: '@bgColorTop',
backgroundColorBottom: '@bgColorBottom',
},
"tabBar": {
"backgroundColor": "@tabBgColor",
"selectedColor": "@tabSelectedColor"
}
}
获取当前主题
// 获取系统主题信息
const systemInfo = uni.getSystemInfoSync()
console.log('当前主题:', systemInfo.theme) // 'light' 或 'dark'
// 监听主题变化
uni.onThemeChange((res) => {
console.log('主题已切换到:', res.theme)
})
CSS 媒体查询适配
/* 默认样式 */
.some-background {
background: white;
}
/* 暗黑模式样式 */
@media (prefers-color-scheme: dark) {
.some-background {
background: #1b1b1b;
}
}
UI 组件适配 (Wot UI)
需要配合虚拟根组件(uni-ku-root) 来做全局共享
npm i -D @uni-ku/root
引入
-
CLI项目: 直接编辑 根目录下的 vite.config.(js|ts)
-
HBuilderX项目: 需要在根目录下 创建 vite.config.(js|ts)
// vite.config.(js|ts)
import { defineConfig } from 'vite'
import UniKuRoot from '@uni-ku/root'
import Uni from '@dcloudio/vite-plugin-uni'export default defineConfig({
plugins: [
// ...plugins
UniKuRoot(),
Uni()
]
})
TIP
若存在改变 pages.json 的插件,需要将 UniKuRoot 放置其后
使用
创建根组件并处理全局配置组件
- CLI项目: 在 src 目录下创建下 App.ku.vue
- HBuilderX项目: 在 根 目录下创建 App.ku.vue
在 App.ku.vue 中标签 <KuRootView /> 代表指定视图存放位置
<!-- 需要确保已注册 WdConfigProvider 组件 -->
<wd-config-provider :theme-vars="themeVars" :theme="theme">
<view :class="`page-wraper ${theme}`">
<KuRootView />
</view>
</wd-config-provider>
编写控制主题组合式函数
@/store/themeStore 仓库管理主题
import { defineStore } from 'pinia'
import { themeColorOptions } from '@/composables/types/theme'
/**
* 简化版系统主题状态管理
* 仅支持跟随系统主题,不提供手动切换功能
* 导航栏颜色通过 theme.json 自动处理
*/
export const useThemeStore = defineStore('theme', {
state: () => ({
theme: 'light',
themeVars: {
darkBackground: '#0f0f0f',
darkBackground2: '#1a1a1a',
darkBackground3: '#242424',
darkBackground4: '#2f2f2f',
darkBackground5: '#3d3d3d',
darkBackground6: '#4a4a4a',
darkBackground7: '#606060',
darkColor: '#ffffff',
darkColor2: '#e0e0e0',
darkColor3: '#a0a0a0',
colorTheme: themeColorOptions[0].primary,
},
}),
getters: {
isDark: state => state.theme === 'dark',
},
actions: {
/**
* 获取系统主题
* @returns 系统主题模式
*/
getSystemTheme() {
// #ifdef MP-WEIXIN
// 微信小程序使用 getAppBaseInfo
const appBaseInfo = uni.getAppBaseInfo()
if (appBaseInfo && appBaseInfo.theme) {
return appBaseInfo.theme
}
// #endif
// #ifndef MP-WEIXIN
// 其他平台使用 getSystemInfoSync
const systemInfo = uni.getSystemInfoSync()
if (systemInfo && systemInfo.theme) {
return systemInfo.theme
}
// #endif
return 'light' // 默认返回 light
},
/**
* 设置主题(仅内部使用)
* @param theme 主题模式
*/
setTheme(theme) {
this.theme = theme
},
/**
* 初始化系统主题
*/
initSystemTheme() {
const systemTheme = this.getSystemTheme()
this.theme = systemTheme
console.log('初始化系统主题:', this.theme)
},
},
})
@/composables/useTheme 系统主题管理组合式API
/**
* 简化版系统主题管理组合式API
*
* 功能特性:
* - 仅跟随系统主题变化
* - 自动响应系统主题切换
* - 导航栏颜色通过 theme.json 自动处理
* - 轻量级,无额外功能
*
* 适用场景:
* - 只需要系统主题适应的简单应用
* - 不需要用户手动控制主题的应用
* - 追求轻量级主题管理的应用
*
* 注意事项:
* - 不支持手动切换主题
* - 不支持主题色自定义
* - 导航栏颜色依赖 theme.json 配置
*
* @example
* ```vue
* <script setup>
* import { useTheme } from '@/composables/useTheme'
*
* const { theme, isDark, themeVars } = useTheme()
* </script>
*
* <template>
* <wd-config-provider :theme-vars="themeVars">
* <view :class="{ 'dark-mode': isDark }">
* <text>当前主题: {{ theme }}</text>
* </view>
* </wd-config-provider>
* </template>
* ```
*/
import { useThemeStore } from '@/store/themeStore'
export function useTheme() {
const store = useThemeStore()
// 组件挂载前初始化系统主题
onBeforeMount(() => {
store.initSystemTheme()
// 监听系统主题变化
if (typeof uni !== 'undefined' && uni.onThemeChange) {
uni.onThemeChange((res) => {
// 系统主题变化时自动更新,导航栏颜色由 theme.json 自动处理
store.setTheme(res.theme)
console.log('系统主题已切换至:', res.theme)
})
}
})
// 组件卸载时清理监听
onUnmounted(() => {
if (typeof uni !== 'undefined' && uni.offThemeChange) {
uni.offThemeChange((res) => {
store.setTheme(res.theme)
})
}
})
return {
// 状态(只读)
theme: computed(() => store.theme),
isDark: computed(() => store.isDark),
themeVars: computed(() => store.themeVars),
}
}
/composables/types/theme
export const themeColorOptions: ThemeColorOption[] = [
{ name: '默认蓝', value: 'blue', primary: '#4D7FFF' },
{ name: '活力橙', value: 'orange', primary: '#FF7D00' },
{ name: '薄荷绿', value: 'green', primary: '#07C160' },
{ name: '樱花粉', value: 'pink', primary: '#FF69B4' },
{ name: '紫罗兰', value: 'purple', primary: '#8A2BE2' },
{ name: '朱砂红', value: 'red', primary: '#FF4757' },
]
📖 详细文档 : Wot UI 暗黑模式配置
样式系统适配 (tailwindcss)
tailwindcss dark 前缀
如果你使用tailwindcss ,可以使用 dark: 前缀来实现暗黑模式样式。
<view class="bg-white dark:bg-gray-900 text-gray-900 dark:text-gray-100">
内容区域
</view>
样式适配方案
<!-- 使用 tailwindcss dark 前缀 -->
<view class="bg-white dark:bg-[var(--wot-dark-background)]
text-gray-800 dark:text-[var(--wot-dark-color)]">
自动适配暗黑模式的内容
</view>
<!-- 使用主题变量 -->
<view class="bg-[var(--wot-bg-color)] text-[var(--wot-text-color)]">
使用主题变量的内容
</view>
最佳实践
<!-- ✅ 推荐:结合官方配置和自定义样式 -->
<view class="bg-white dark:bg-[var(--wot-dark-background2)]">
<!-- ❌ 不推荐:硬编码颜色 -->
<view style="background: #000; color: #fff;">