# 实现一套代码在多端有不同表现
在小程序中展示 A 内容或者执行 A 逻辑,但在 APP 中展示 B 内容或者执行 B 逻辑。
这种情况就属于条件需求:针对不同的设备和运行环境,预期完成不同的逻辑和页面显示。
为了支持跨端项目不同平台有不同呈现/逻辑的需求,多端框架支持条件编译语法。
- 目前支持
wxml
、wxss
、js/ts
、json
,less/sass
,wxss
等文件类型,资源支持通过配置区分不同平台。 - json 文件支持的标记:
mini-wechat
(微信小程序)、mini-android
(安卓 APP)、mini-ios
(苹果 APP)。 wxml
、js
、less/wxss
内置的标记:ANDROID
、IOS
、MP
和NATIVE
(Android 或 iOS)。- 支持 || 语法表示同时兼容多种条件,如
<!-- #if MP || ANDROID -->
(json 不支持该写法)。 - 条件编译采用注释语法,通过不同的条件编译不同的内容到不同的平台产物中。
接下来简单演示一下如何开启条件编译,以及分别演示各个文件如何编写条件规则。
# 一、开启条件编译
在小程序开发者工具中「详情-本地设置-启用条件编译」,开启后项目在运行或者编译时会自动根据编写条件区分内容。
# 二、编写演示
所有文件基本都遵循下列原则:
如果标记没有
#if #endif
闭环,则会报错error:#if without #endif
在一个条件组中,编译只会取第一个匹配到的内容
NATIVE
与IOS || ANDROID
等效(JSON 文件不适用)
# 2.1 WXML 文件
<!-- #if MP -->
<view>小程序展示的信息</view>
<!-- #elif IOS || ANDROID -->
<view>APP展示的信息(包含 iOS 和 Android)</view>
<!-- #endif -->
<!-- #elif MP -->
<view>小程序展示的信息</view>
<!-- #elif NATIVE -->
<view>NATIVE和IOS || ANDROID等效,在 iOS 和 Android 中显示</view>
<!-- #endif -->
<!-- #if MP -->
<view>小程序展示的信息</view>
<!-- #elif IOS -->
<view>iOS 匹配到这里就展示,下面 NATIVE 不会展示</view>
<!-- #elif NATIVE -->
<view>因为 iOS 上面匹配了,所以这里只在 Android 中显示</view>
<!-- #endif -->
<!-- #if MP -->
<view>小程序展示的信息</view>
<!-- #elif NATIVE -->
<view>在 iOS 和 Android 中显示</view>
<!-- #elif IOS -->
<view>因为上面 NATIVE 已经匹配了,这里不可能展示出来</view>
<!-- #endif -->
<!-- #if ANDROID -->
<view>只有安卓展示的信息</view>
<!-- #endif -->
# 2.2 WXSS 文件(css/sass/less 适用)
wxss 的编译条件可以在样式括号内,也可以在外层。
.test-view{
/* #if MP */
color: red;
/* #elif IOS */
color: green;
/* #elif ANDROID */
color: yellow;
/* #endif */
/* #if MP || ANDROID */
background-color: black;
/* #endif */
}
/* #if MP */
.top{
position: fixed;
}
/* #endif */
# 2.3 JS 文件(TS 适用)
// #if MP
console.log('只在微信小程序执行')
// #elif IOS
console.log('只在 iOS 执行')
// #elif ANDROID
console.log('只在 Android 执行')
// #endif
// #if MP
console.log('只在微信小程序执行')
// #elif NATIVE
console.log('只在 iOS 和 Android 执行')
// #elif ANDROID
console.log('因为上面 NATIVE 已经匹配了,这里不可能执行')
// #endif
// #if MP || IOS
console.log('在微信小程序和 iOS 执行')
// #endif
需要注意,js 和 ts 的条件包含需要是完整的执行体,而不可直接拆分代码行,下图这种例子是不支持的,如果你觉得冗余,建议封装为函数。
# 2.4 JSON 文件
在项目中只针对 app.json 和 页面的 json 有效,在特定的 mini-wechat 、 mini-ios、mini-android 里的内容将在编译运行时,覆盖原来的。
{
"window": {
"navigationBarTitleText": "Weixin",
},
"mini-wechat": {
"window": {
"navigationBarTitleText": "wechat demo"
}
},
"mini-ios": {
"window": {
"navigationBarTitleText": "iOS demo"
}
},
"mini-android": {
"window": {
"navigationBarTitleText": "android demo"
}
}
}
# 三、资源差异打包
在 app.json 中配置 static 字段,指定每个目录/文件只能发布到特定的平台。
比如下面例子,表示 miniprogram/pages/logs 目录下的所有文件,只在 iOS APP 编译时被打包,其他平台不会包含。
{
"static": [
{
"pattern": "miniprogram/pages/logs/*", // 支持glob语法
"platforms": ['mini-ios']
}
]
}