现在用Uniapp做APP/小程序,是很快速、很成熟的方案了,除非是要求特别挑剔的项目,否则一般不会用Android/iOS原生开发。除了Uniapp,还有Taro、Rax、Flutter等工具,都是可以实现一套代码,多终端应用的生成。但是针对一套代码,能同时生成APP、小程序不假,可生成的产品,也不是说就能直接使用的。APP和小程序虽然都是运行在移动端,但他们的底层环境、前端显示、页面生命周期等架构参数并不相同,需要针对终端的不同做代码适配。也就是说,一套代码开发的APP和小程序,不能直接使用,还需要做兼容性适配。
今天丁老师就同步开发APP/小程序的兼容性适配做一下介绍,本文重点在于介绍APP和小程序同步开发前端部分的兼容性和解决方案。
一、页面顶部兼容处理
在微信小程序中,顶部有两部分和APP不同,一个是页面顶部的高度,一个是页面顶部的宽度。
页面顶部的高度:
APP和微信小程序关于页面顶部的高度(包含手机状态栏、电池电量等),都可以使用uni.getSystemInfoSync().statusBarHeight来获取。但是微信小程序包含右侧的胶囊按钮,无法去掉,并且该胶囊的尺寸根据不同手机屏幕大小而不同,高度位置都不固定,只能动态计算高度,如图:

微信小程序页面顶部高度计算代码:
const menu = uni.getMenuButtonBoundingClientRect();
//标题栏(胶囊所在区域,不含状态栏)
const titleHeight = menu.height + (menu.top - statusBarHeight)*2;
//顶部总高度=状态栏 + 标题栏(你的navbar组件整体高度)
const customBar = statusBarHeight + titleHeight;而APP则没有胶囊,可以将页面的导航栏高度固定为44px。
APP页面顶部高度的计算代码:
uni.getSystemInfoSync().statusBarHeight+44兼容APP和小程序的页面顶部高度计算代码:
onLoad() {
const systemInfo = uni.getSystemInfoSync();
const statusBarHeight = systemInfo.statusBarHeight;
let customBar = 0;
//微信
#ifdef MP-WEIXIN
try{
const menu = uni.getMenuButtonBoundingClientRect();
const titleHeight = menu.height + (menu.top - statusBarHeight) * 2;
customBar = statusBarHeight + titleHeight;
}
catch(e){
customBar = statusBarHeight + 44;
}
// #endif
//APP
// #ifdef APP-PLUS
customBar = statusBarHeight + 44;
// #endif
console.log('状态栏',statusBarHeight,'navbar总高度',customBar);
this.statusBarHeight = statusBarHeight;
this.customBar = customBar;
}二、CSS兼容
关闭橡皮筋弹性回弹bounce
微信小程序的页面回弹靠是需要设置disableScroll:true,即关闭页面滚动,然后设置scroll-view的bounces="false"
APP的页面回弹在则是要在pages.json中设置,可针对全局,或单独页面设置app-plus: {bounce:"none"}。备注:安卓APP默认无bounce回弹。
背景图片
APP的css中,关于background-image,可以随意使用本地图片。而微信小程序则无法使用大于50kb的本地图片作为背景图,对于尺寸较大的图片只能使用远程图片。
rpx和px的像素兼容
微信小程序使用rpx作为像素单位,APP使用px作为像素单位,但在实际开发中,可以统一设置为以px为单位,只不过在生成应用后,部分小程序和APP的像素显示大小不会完全一致,需要进行兼容性区分处理。
注:APP和小程序CSS兼容性区分处理代码:
/* #ifdef APP-PLUS */
这里写APP的CSS代码
/* #endif */
/* #ifndef APP-PLUS-NVUE */
这里写APP NVUE页面的CSS代码
/* #endif */
/* #ifdef MP-WEIXIN */
这里写微信小程序的CSS代码
/* #endif */注:以上区分代码,不用每个样式重复写,99%的样式可以不区分,写成公用样式,然后可以针对某个样式,单独区分APP和小程序重写。
三、API兼容处理
uni.getMenuButtonBoundingClientRect()
这个方法是获取菜单按钮(就是小程序右上角胶囊按钮)的布局位置信息。微信小程序有这个方法,APP则没有。
uni.getPrivacySetting
微信小程序的方法,显示隐私协议,小程序上架时必须使用。APP则没有这个方法。
uni.getStorage
微信小程序最多存储10mb,APP无限制。
plus.nativeUI
APP的本地API方法,小程序没有这种方法。
分享
微信小程序使用onShareAppMessage实现页面分享,APP则使用uni.share方法实现分享功能。
@tap.stop
微信小程序支持@tap.stop方法,APP则不支持。
四、其他兼容处理
微信支付
微信小程序使用uni.requestPayment,而APP的微信支付则需要使用APP端微信SDK,并且支付签名、预下单参数、openid获取逻辑完全不同。
页面层级
比如video组件,APP的video组件层级最高,上边无法放覆盖物,复杂的业务需要使用NVUE才可以实现。而微信小程序的video组件上则可以放其他覆盖物。
Picker
主要是指地区三级联动选择,微信小程序可以使用region自动显示地区三级且联动,而APP则需要自己加载地区数据,自己写联动方法(需后端配合)。
五、全文总结
上述内容就是丁老师,根据实际开发经验而总结的、一些需要区分APP和小程序兼容的地方。当然这篇文章肯定还有很多地方没有提及,写的也不是很到位,只不过目前丁老师能想到的就是这些,基本上涉及到多端应用的兼容性开发都涉及。
写这篇的文章的目的就是作为备用,现在同步开发APP和小程序的人越来越多了,并且随着鸿蒙系统的普及,鸿蒙的兼容性也要单独处理(关于鸿蒙的兼容性以后另开一篇文章介绍)。如果你有幸看到这篇文章,同时也在开发APP或小程序,涉及兼容性处理,欢迎联系丁老师交流和探讨,丁老师如果有写的不对的地方,也欢迎联系丁老师进行批评和指正。
问题:在html中,如果checkbox为已选状态,进入下一个页面后再点后退时,该checkbox还是为已选中状态,但是依赖该checkbox选中后的事件却无法执行。解决:这种情况下,对checkbox的input设置autocompl...
在使用前端框架Nuxt 3开发时,如何配置自定义的scss文件路径呢?有同学使用loadPaths: ['@/assets/css']来设置路径,但是无效,是因为在loadPaths中,@符号不起作用,不能代表根目录。正...
Bagisto是一款强大的跨境电商平台软件,很多客户在初次安装和使用时,会或多或少遇到一些解决不了的情况。丁老师整理了一些常见的Bagisto问题以及解决方法以供查阅。问:安装Bagisto时出现"Command compos...
有同学咨询,想知道怎么样使用Android Studio来构建Flutter应用项目,今天丁老师来教你。在Android Studio中,选择顶部菜单的Build-Flutter-Build APk,就可以生成Flutter项目的APK...
目前随着AI的不断发展,Vibe Coding的持续普及,诞生了大量的AI软件开发工具(IDE),通过这些工具,可以让一个不懂软件开发的人、没有任何技术能力的人使用AI来开发出想要的软件、网站等等。有同学咨询丁老师,使用AI开发的软件,可以...
在使用idea旗下的产品,如intellij idea,php storm,web storm时,有的时候编辑前端页面JS,在换行时经常会自动出现个}大括号,这一点程序不是很智能,其实后边都已经有括号了。比如下图这样:那么如何解决这个问题呢...
pdf添加水印,可以使用专业的pdf工具,如Adobe Acrobat、福昕PDF阅读器等,支持文字和图片形式的添加水印,支持透明度设置、水印位置设置等。图片添加水印,可以使用photoshop软件,但是photoshop太大了,而且使用起...
内网穿透,是指外网可以访问内网,没有固定IP的服务器,所以需要中间件来进行通讯,目前稳定成熟的中间件软件,要么价格太贵,要么就是只能使用标准服务,不能完全的定制化。那么,到底有没有一个性价比最优的方案呢?回答是肯定的,答案就是使用云服务器+...