官方文档:DarkMode 适配指南 @darkmode | uni-app官网

uniapp适配暗黑模式配置plus.nativeUI.setUIStyle适配DarkMode配置_uniapp暗黑模式-CSDN博客

可先看以上文章,这里分享几个避坑点:

(1)仅支持"black"/"white”的设置:

navigationBarTextStyle(顶部title文字颜色)

tabbar-borderStyle(底部tabbar上面的border颜色)App 2.3.4+ 、H5 3.0.0+

仅支持"dark"/"light”的设置:

backgroundTextStyle(下拉Loading的样式)在globalStyle里配置该选项只有微信小程序支持,其他平台支持单个页面配置。

(2)页面背景颜色我是统一在App.vue里修改:

 /* 默认light */
 body,
 page {
	background-color: #fff;
 }

/*深色模式时 */

 @media (prefers-color-scheme: dark) {
	body,page{
		background-color: #191919;  //微信小程序有个默认深色模式背景#191919
	}
}

/* 当然可以定义一些全局变量,以统一配置颜色 */

 :root,
 page {
 	--dark: #343a40;
	--dark-gray: #D3D3D3;
	--dark-dark: #1f1f1e;
	--dark-dark2: #3B3B3B;
	--dark-gray2: #6B6C6E;
	--wx_dark_bg: #191919;
 }

(3) uni-ui并没有支持深色模式,因此需要自己在uni_modules里找到组件在css里修改,scss或less都支持@media (prefers-color-scheme: dark)

因为很多组件都用了内联样式,所以需在样式后加上!important更为稳妥,当然也可以在使用到这些组件的页面用::v-deep 修改,但是只对设置了的页面有效,建议在组件里修改。

	@media (prefers-color-scheme: dark) {
		.uni-numbox-btns{
			background-color: var(--dark)!important;
		}
		
		.uni-numbox__value,.uni-numbox--text{
			color: var(--dark-gray)!important;
		}
	}

关于App适配的补充:(安卓端,IOS未测试)

Nvue页面我采用的动态加class方式实现,在原代码外层套一个view元素

<!-- 注意Nvue页面加:key="theme"可以在系统颜色模式变化时热更新页面颜色 -->

<!-- vue页面可以自动跟随系统颜色变化热更新 -->

<view :class="theme === 'dark' ? 'isDark' :''" class="myPage" :key="theme">
</view>
	.myPage {
		display: flex;
		flex-direction: column;
	}

	.isDark .xxxx1,
	.isDark .xxxx2,
	.isDark .xxxx3,
	.isDark .xxxx4{
		background-color: #1f1f1e !important;
	}
	plus.nativeUI.setUIStyle('auto');
	const theme = ref(plus.navigator.getUIStyle());
    let preTheme = theme.value;
//因为我的nvue页面用了rich-text,要动态修改rich-text的颜色,这里我用preTheme把前面的theme保存起来,如果没有这个需求,可以忽略
	onShow(() => {
		theme.value = plus.navigator.getUIStyle();
		if (preTheme !== theme.value) {
			preTheme = theme.value;
			newsNotesArr.value = updateColor(newsNotesArr.value, theme.value === 'dark' ? 'lightToDark' :
					'darkToLight')  //在这里更新rich-text的颜色

		}
	})


//如果没有rich-text需求,以下可以忽略
	function updateColor(data, type) {
		data.forEach(group => {
			group.forEach(item => {
				// 更新 div 的样式
				if (item.attrs && item.attrs.style) {
					if (type === 'darkToLight') {
						item.attrs.style = item.attrs.style.replace(/#d3d3d3/g, '#343a40');
					} else {
						item.attrs.style = item.attrs.style.replace(/#343a40/g, '#d3d3d3');
					}
				}
				// 如果有子节点,递归更新
				if (item.children) {
					item.children.forEach(child => {
						// 更新 text 的样式
						if (child.attrs && child.attrs.style) {
							if (type === 'darkToLight') {
								child.attrs.style = child.attrs.style.replace(/#d3d3d3/g,
									'#343a40');
							} else {
								child.attrs.style = child.attrs.style.replace(/#343a40/g,
									'#d3d3d3');
							}
						}
					});
				}
			});
		});
		return data
	}

//因为我的newsNotesArr缓存在了storage中,所以我在保存newsNotesArr时也同时存了rich-text的颜色:
	
        const len = v.data.length; //v.data是服务器返回数据
        let arrItem = [];
		for (let i = 0; i < len; i++) {
				arrItem.push([{
					name: 'div',
					attrs: {
						style: `fontSize:14px;color:${theme.value === 'dark' ? '#d3d3d3' : '#343a40'}`
					},
					children: [{
						type: 'text',
						text: v.data[i]['title'],
						attrs: {
							style: `fontSize:14px;color:${theme.value === 'dark' ? '#d3d3d3' : '#343a40'}`
						}
					}]
				}])
			}
			arrItem[0][0]['themeType'] = theme.value //标记了当前主题
			newsNotesArr.value = arrItem;


//在页面首次加载时,判断一下storage里的rict-text颜色是否与主题一致:
	const newsNotesArr = ref(uni.getStorageSync('newsNotesArr') || [])
	if (newsList.value.length === 0) {
		//加载新数据
	} else {
		if (newsNotesArr.value[0][0]['themeType'] !== theme.value) { 
//如果主题不一致就要修改rich-text的颜色以适配
			newsNotesArr.value = updateColor(newsNotesArr.value, theme.value === 'dark' ? 'lightToDark' :
				'darkToLight')
		}
	}

By the way,

webview里的html文件也动态支持媒体查询 @media (prefers-color-scheme: dark) {},所以不必担心web-view适配问题

有一种情况是web-view加载的地图如果要支持深色模式,那么就在src参数里加上xxx=theme(theme来源于uni.getSystemInfoSync().theme),同样支持动态更新。

微信小程序的暗黑模式适配似乎存在微信官方Bug:

测试环境:安卓10,鸿蒙3.0系统

微信App深色模式为跟随系统,打开小程序,按Home键退回桌面,在手机设置内更换系统的颜色模式,再打开小程序,虽然有小程序重新加载的动画,【但首页页面主体颜色并没有实时更新,需要点右上角"..."选重新进入才会正常】注:首页原生导航栏和原生tabbar的颜色都更新了,除首页外其他页面颜色也都正常跟随更新,但首页主体内容颜色模式是相反的,如果此时再重复上述步骤在手机设置内改回之前的颜色,那么首页页面内容颜色和原生组件颜色模式会始终相反,需要点右上角"..."选重新进入或者冷启动才会正常。测试了已适配暗黑模式的微信小程序IT之家和本地哥拖车救援都有这个问题

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐