uniapp深色模式适配几个注意点
官方文档: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之家和本地哥拖车救援都有这个问题
更多推荐
所有评论(0)