uni-app多端应用开发:常见跨端兼容问题及处理策略

一、跨端兼容

每个端有每个端的特点,有的能被抹平,有的不可能被抹平。 跨端,不是把web的习惯迁移到全平台。而是按照uni的写法,然后全平台使用。 按照uniapp规范开发可以保证多平台兼容,但每个平台有自己的一些特性。 uni-app在跨平台的过程中,不牺牲平台特色,不限制平台的能力使用。 应用开发中,90%的常规开发,比如界面组件、联网等api,uni-app封装为可跨多端的API。 而各个端的特色功能,uni-app引入条件编译。可以优雅的在一个项目里调用不同平台的特色能力。

二、条件编译

条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。

支持的文件

  • .vue/.nvue/.uvue
  • .js/.uts
  • .css
  • pages.json
  • 各预编译语言文件,如:.scss、.less、.stylus、.ts、.pug

注意:

条件编译是利用注释实现的,在不同语法里注释写法不一样。

xml 复制代码
js/uts使用 // 注释
css 使用 /* 注释 */
vue/nvue/uvue 模板里使用 <!-- 注释 -->

使用条件编译请保证编译前和编译后文件的语法正确性,即要保障无论条件编译是否生效都能通过语法校验。

三、兼容处理

1、API兼容

1.1、选择图片的方法

从本地相册选择图片或使用相机拍照。

css 复制代码
uni.chooseImage(OBJECT)

微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。

拍摄或从手机相册中选择图片或视频。

css 复制代码
uni.chooseMedia(OBJECT)

这个方法目前App和H5端都不支持,所以我们要做兼容处理。

小程序端使用方法判断

javascript 复制代码
// #ifdef MP-WEIXIN
uni.chooseMedia({
  count: 1,
  mediaType: ['image'],
  success: (res) => {
    console.log(res)
  }
})
// #endif

H5和APP端使用方法判断

javascript 复制代码
// #ifdef H5 || APP-PLUS
uni.chooseImage({
  count: 1,
  success: (res) => {
    console.log(res)
  }
});
// #endif
1.2、微信登录
ini 复制代码
// #ifdef MP-WEIXIN
wx.login({
  success: res => {
    // 发送 res.code 到后台换取 openId, sessionKey, unionId
  }
})
// #endif
1.3、微信支付
php 复制代码
// #ifdef MP-WEIXIN
wx.requestPayment({
  timeStamp: '',
  nonceStr: '',
  package: '',
  signType: 'MD5',
  paySign: '',
  success(res) {},
  fail(res) {}
})
// #endif

2、样式兼容

2.1、小程序端不支持*选择器

不可以使用

css 复制代码
* {
    color: #333;
}

可以使用这样的写法

css 复制代码
view,
text {
    color: #333;
}
2.2、页面视口差异(tabBar页,普通页)

小程序和APP底部的tabBar是不包含在页面高度里的,而H5端tabBar是包含的页面高度里面的。

2.2.1、定位时的兼容

不可以使用

css 复制代码
.xxx{
  position:fixed;
  bottom:0;
}

可以使用这样的写法

css 复制代码
.xxx{
  position:fixed;
  bottom:var(--window-bottom);
}
2.2.2、上拉加载更多的高度兼容

不可以使用

css 复制代码
page{
  height:100vh;
}

可以使用这样的写法

css 复制代码
page{
  height:100%;
}

2.3、H5端默认开启scoped

H5端是单页面应用,为了隔离页面间的样式默认启用了 scoped。 非H5端默认并未启用 scoped,如需要隔离组件样式可以在 style 标签增加 scoped 属性。 H5端默认启用了 scoped样式隔离,导致组件样式无效。

可以把组件样式抽离,组件中和页面中分别引入。

组件中引入样式

xml 复制代码
<style lang="scss">
// 此处引入组件样式
@import '@/components/styles/common.scss'
</style>

页面中引入样式

xml 复制代码
<style lang="scss">
/* #ifdef H5 || APP_PLUS */
@import '@/components/styles/common.scss';
/* #endif */
</style>

3、组件兼容

3.1、button按钮的联系客服

需要处理只在小程序端生效

xml 复制代码
<!-- #ifdef MP-WEIXIN -->
<button open-type="contact">客服</button>
<!-- #endif -->
3.2、button按钮的获取手机号

需要处理只在小程序端生效

xml 复制代码
<!-- #ifdef MP-WEIXIN -->
<button open-type="getPhoneNumber" @getphonenumber="decryptPhoneNumber">获取手机号</button>
<!-- #endif -->

四、判断平台

平台判断有 2 种场景,一种是在编译期判断,一种是在运行期判断。

  • 编译期判断 编译期判断,即条件编译,不同平台在编译出包后已经是不同的代码。
perl 复制代码
// #ifdef H5
alert('只有h5平台才有alert方法');
// #endif

如上代码只会编译到 H5 的发行包里,其他平台的包不会包含如上代码。

  • 运行期判断 运行期判断是指代码已经打入包中,仍然需要在运行期判断平台。
arduino 复制代码
switch (uni.getSystemInfoSync().platform) {
	case 'android':
		console.log('运行Android上');
		break;
	case 'ios':
		console.log('运行iOS上');
		break;
	default:
		console.log('运行在开发者工具上');
		break;
}

如有必要,也可以在条件编译里自己定义一个变量,赋不同值。在后续运行代码中动态判断环境。

相关推荐
红色的小鳄鱼1 分钟前
Vue 教程 自定义指令 + 生命周期全解析
开发语言·前端·javascript·vue.js·前端框架·html
coloma20123 分钟前
COCOS代码动态增加刚体和碰撞体的方法
前端·uv
想逃离铁厂的老铁7 分钟前
Day60 >> 94、城市间货物运输1️⃣ + 95、城市间货物运输 2️⃣ + 96、城市间货物运输 3️⃣
java·服务器·前端
GISer_Jing1 小时前
WebGL跨端兼容实战:移动端适配全攻略
前端·aigc·webgl
迦南giser1 小时前
前端性能——传输优化
前端
小白_ysf1 小时前
Vue 中常见的加密方法(对称、非对称、杂凑算法)
前端·vue.js·算法
人工智能训练8 小时前
【极速部署】Ubuntu24.04+CUDA13.0 玩转 VLLM 0.15.0:预编译 Wheel 包 GPU 版安装全攻略
运维·前端·人工智能·python·ai编程·cuda·vllm
会跑的葫芦怪8 小时前
若依Vue 项目多子路径配置
前端·javascript·vue.js
pas13611 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
摇滚侠11 小时前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6