Uniapp运行环境判断和解决跨端兼容性详解
Uniapp
运行环境判断和解决跨端兼容性
开发环境和生产环境
uniapp
可通过process.env.NODE_ENV
判断当前环境是开发环境还是生产环境,一般用于链接测试服务器或者生产服务器的动态切换。在HX
中,点击运行
编译出来的代码是开发环境,点击发行
编译出来的代码是生产环境。
if(process.env.NODE_ENV === 'development'){
console.log('开发环境')
}else{
console.log('生产环境')
}
跨端兼容
uniapp
已将常用的组件,js api
封装到框架中,开发者按照uniapp
规范开发即可保证多平台兼容,大部分业务均可直接瞒住,但每个平台有自己的特征,因此会存在一些无法跨平台情况,大量写if else
会造成代码执行性能低下和管理混乱,编译到不同的工程后二次修改会让后续升级变得非常麻烦,在C
中,通过#ifdef
,#ifndef
的方式,为windows
,mac
,等不同的OS
编译不同的代码,uniapp
也参考了这个思路,为uniapp
提供了条件编译手段,在一个工程项目里优雅的完成了平台个性化实现。
条件编译解决跨端兼容性
uni-app
平台有两种场景,一种是在编译期条件编译判断,一种是在运行期判断。
条件编译语法
条件编译使用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同的平台。写法以#ifdef
或#ifndef
加%PLATFORM
开头,以#endif
结尾。
#ifdef
:if defined
仅在某平台存在。#ifndef
:if not defined
除了某平台均存在。%PLATFORM
:平台名称。
%PLATFORM
取值表
值 | 平台 |
---|---|
APP-PLUS | App |
APP-PLUS-NVUE或APPNVUE | App nvue |
H5 | H5 |
MP-WEIXIN | 微信小程序 |
MP-ALIPAY | 支付宝小程序 |
MP-BAIDU | 百度小程序 |
MP-TOUTIAO | 字节跳动小程序 |
MP-QQ | QQ 小程序 |
MP-360 | 360 小程序 |
MP | 微信小程序/支付宝小程序/百度小程序/字节跳动小程序/QQ小程序/360小程序 |
QUICKAPP-WEBVIEW | 快应用通用(包含联盟、华为) |
QUICKAPP-WEBVIEWUNION | 快应用联盟 |
QUICKAPP-WEBVIEWHUAWEI | 快应用华为 |
实列说明:
#ifdef APP-PLUS,#endif
,需条件编译的代码,仅出现在App
平台下的代码。#ifndef H5,#endif
,需条件编译的代码,除了H5
平台,其它平台均存在的代码。#ifdef H5 || MPWEIXIN,#endif
,需条件编译的代码,在H5
平台或微信小程序平台存在的代码(这里只有||
,不可能出现&&
,因为没有交集)。
支持的文件:.nvue
,.vue
,.js
,.css
,pages.json
。
**各预编译语言文件:**如:.scss
,.less
,.stylus
,.ts
,.pug
。
注意:
条件编译是利用注释实现的,在不同语法里注释写法不一样,js
使用//注释
、css
使用/* 注释 */
、vue/nvue
模板里使用 <!-- 注释 -->
,条件编译 APP-PLUS
包含 APP-NVUE
和 APP-VUE
,APP-PLUS-NVUE
和APP-NVUE
没什么区别,为了简写后面出了APP-NVUE
;
组件(模板)的条件编译
<!-- #ifdef %PLATFORM% -->
平台特有的组件
<!-- #endif -->
示例:
<template>
<view>
<!-- #ifdef APP-PLUS -->
<view>APP中显示</view>
<!-- #endif -->
<!-- #ifndef APP-PLUS -->
<view>不在APP中显示</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN || H5 -->
<!-- 还支持多平台同时编译,使用 || 来分隔平台名称 -->
<view>在微信小程序或H5端显示_点击下载APP</view>
<!-- #endif -->
</view>
</template>
结果:
API(js)
的条件编译
// #ifdef %PLATFORM%
平台特有的API实现
// #endif
示例:
<template>
<view></view>
</template>
<script>
export default {
data() {
return {
// #ifdef APP-PLUS
title: '我是APP端',
// #endif
}
},
onLoad() {
this.test1()
},
methods: {
test1() {
// #ifdef H5
console.log('兼容H5平台')
// #endif
// #ifdef MP-WEIXIN
console.log('兼容微信小程序平台')
// #endif
}
}
}
</script>
<style></style>
效果:
样式 (style)
的条件编译
/* #ifdef %PLATFORM% */
平台特有样式
/* #endif */
注意: 样式的条件编译,无论是 css
还是 sass/scss/less/stylus
等预编译语言中,必须使用 /*注释*/
的写法。
示例:
<template>
<view>
<view class="test">
</view>
</view>
</template>
<script>
export default {
data() {
return {
// #ifdef APP-PLUS
title: '我是APP端',
// #endif
}
},
onLoad() {
this.test1()
},
methods: {
test1() {
// #ifdef H5
console.log('兼容H5平台')
// #endif
// #ifdef MP-WEIXIN
console.log('兼容微信小程序平台')
// #endif
}
}
}
</script>
<style lang="scss">
.test {
width: 100px;
height: 100px;
/* #ifdef MP */
background: red;
/* #endif */
/* #ifdef MP-WEIXIN */
background: yellow;
/* #endif */
/* #ifdef H5 */
background: green;
/* #endif */
}
</style>
pages.json
的条件编译
下面的页面,只有运行至 App
时才会编译进去。不同平台下的特有功能,以及小程序平台的分包,都可以通过 pages.json
的条件编译来更好地实现。这样,就不会在其它平台产生多余的资源,进而减小包体积。
示例:
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
}
// #ifdef APP-PLUS
, {
"path": "pages/wenda/wenda",
"style": {
"navigationBarTitleText": "问答"
}
}
// #endif
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}
注意:
在 #ifdef APP-PLUS
和 #endif
预编译指令之间,如果只有一个配置项,那么这个配置项后面不应该有逗号
。这是因为预编译指令可能会导致这部分代码被移除,从而留下一个多余的逗号,造成 JSON
解析错误。
static
目录的条件编译
在不同平台,引用的静态资源可能也存在差异,通过 static
的的条件编译可以解决此问题,static
目录下新建不同平台的专有目录(目录名称同 %PLATFORM% 值域,但字母均为小写)
,专有目录下的静态资源只有在特定平台才会编译进去。
如以下目录结构, a.png
只有在微信小程序平台才会编译进去, b.png
在所有平台都会被编译。
┌─static
│ ├─mp-weixin
│ │ └─a.png
│ └─b.png
├─main.js
├─App.vue
├─manifest.json
└─pages.json
运行期判断IOS/Android
平台
Android
和 iOS
平台不支持通过条件编译来区分,如果需要区分Android
、iOS
平台,请通过调用uni.getSystemInfo
来获取平台信息。
运行期判断: 运行期判断是指代码已经打入包中,仍然需要在运行期判断平台,此时可使用uni.getSystemInfoSync().platform
判断客户端环境是 Android
、iOS
还是小程序开发工具(在百度小程序开发工具、微信小程序开发工具、支付宝小程序开发工具中使用 uni.getSystemInfoSync().platform
返回值均为 devtools
)。如有必要,也可以在条件编译里自己定义一个变量,赋不同值。在后续运行代码中动态判断环境。
判断是否为: IOS
平台的APP
端
<template>
<view></view>
</template>
<script>
export default {
data() {return {}},
onLoad() {
switch (uni.getSystemInfoSync().platform) {
case 'android':
console.log('运行Android上')
break;
case 'ios':
console.log('运行iOS上')
break;
default:
console.log('运行在开发者工具上')
break;
}
},
methods: {}
}
</script>
<style lang="scss"></style>
效果:
如有必要,也可以在条件编译里自己定义一个变量,赋不同值。在后续运行代码中动态判断环境。
<template>
<view>
<view v-if="isIosApp">
是IOS平台的APP端
</view>
<view v-else>
不是IOS平台的APP端
</view>
</view>
</template>
<script>
export default {
data() {
return {
isIosApp: false, // 是否为 IOS平台的APP端
}
},
onLoad() {
// #ifdef APP-PLUS
this.isIosApp = uni.getSystemInfoSync().platform === 'ios'
// #endif
},
}
</script>
效果:
Uniapp
运行环境判断和解决跨端兼容性详解完结~