UniApp 的核心优势在于“一次开发,多端运行”,但不同平台(微信小程序、H5、App、支付宝小程序等)在 API、组件、样式甚至运行机制上都存在差异。如果粗暴地用 if (process.env.PLATFORM === 'mp-weixin') 判断,代码会变得难以维护。UniApp 提供的条件编译机制,允许我们在编译阶段按平台裁剪代码,既保证运行效率,又让多端差异处理得干净优雅。本文总结 10 个实用技巧,帮你彻底掌握条件编译。
1. 基础语法:三种注释式条件编译
UniApp 的条件编译以特殊注释形式存在,支持 #ifdef、#ifndef、#endif 三种指令:
// #ifdef MP-WEIXIN
console.log('仅微信小程序执行')
// #endif
// #ifndef H5
console.log('除 H5 外都执行')
// #endif
平台标识符区分大小写,常用值包括:MP-WEIXIN、MP-ALIPAY、MP-BAIDU、H5、APP-PLUS、APP-VUE、APP-NVUE。注意 APP-PLUS 代表整个 App 平台,而 APP-VUE 和 APP-NVUE 用于区分渲染引擎。
技巧:在 JS 中必须使用 // 注释,在 CSS 中使用 /* */,在 template 中使用 <!-- -->。写错注释类型会导致编译失效。
2. 在 template 中优雅控制组件显示
不同平台支持的组件不同,比如微信小程序的 <official-account> 只在微信端有效。用条件编译包裹,避免其他平台报错:
<template>
<view>
<!-- #ifdef MP-WEIXIN -->
<official-account @load="onLoad"></official-account>
<!-- #endif -->
<!-- #ifndef MP-ALIPAY -->
<ad unit-id="xxx"></ad>
<!-- #endif -->
</view>
</template>
这样编译到支付宝小程序时,<ad> 组件会被完全移除,不会产生冗余代码。
3. 样式差异化:CSS 中的条件编译
各端默认样式差异巨大,比如 scroll-view 的滚动条、button 的默认边框。用条件编译写平台专属样式:
/* #ifdef MP-WEIXIN */
.btn {
border: none;
}
/* #endif */
/* #ifdef H5 */
.btn {
cursor: pointer;
}
/* #endif */
注意:CSS 条件编译只支持 /* */ 注释,且不能嵌套在已有选择器内部,必须独立成块。
4. 处理 API 差异:封装统一接口
不同端的 API 名称和参数可能不同。推荐做法是:用条件编译封装统一函数,对外暴露一致接口。
// utils/storage.js
export function setStorage(key, value) {
// #ifdef MP-WEIXIN
wx.setStorageSync(key, value)
// #endif
// #ifdef H5
localStorage.setItem(key, JSON.stringify(value))
// #endif
// #ifdef APP-PLUS
plus.storage.setItem(key, JSON.stringify(value))
// #endif
}
调用方无需关心平台,代码整洁且易于扩展新平台。
5. 使用 #ifdef 与 #ifndef 组合处理“仅某端”和“排除某端”
常见场景:某功能只在 App 和微信小程序可用,其他端隐藏。
// #ifdef APP-PLUS || MP-WEIXIN
startLivePlayer()
// #endif
UniApp 支持 ||(或)和 &&(与)逻辑运算符。但注意:不要写 ! 取反,应使用 #ifndef 替代。
6. 在 pages.json 中条件编译
pages.json 支持条件编译,用于控制不同端的页面路径、导航栏样式、tabBar 等:
{
"pages": [
{
"path": "pages/index/index",
"style": {
// #ifdef MP-WEIXIN
"navigationStyle": "custom"
// #endif
}
}
]
}
技巧:利用条件编译为 H5 单独配置 titleNView,为小程序配置 navigationBarTitleText,避免手动判断。
7. 处理平台特有生命周期
某些生命周期仅特定平台触发,如 onShareTimeline 仅微信小程序支持。用条件编译包裹,避免其他端警告:
export default {
onLoad() {},
// #ifdef MP-WEIXIN
onShareTimeline() {
return { title: '分享标题' }
},
// #endif
}
8. 条件编译实现“平台专属页面”
有时某页面只在小程序存在(如微信授权页)。在 pages.json 中条件编译注册,并在跳转时也加条件判断:
// #ifdef MP-WEIXIN
uni.navigateTo({ url: '/pages/auth/auth' })
// #endif
注意:如果页面未注册,跳转会失败。务必确保注册与跳转的条件编译平台一致。
9. 利用 process.env.UNI_PLATFORM 做运行时判断
条件编译是编译时裁剪,而 process.env.UNI_PLATFORM 是运行时变量。两者结合可应对复杂场景:
// #ifdef MP
const platform = process.env.UNI_PLATFORM // 'mp-weixin'
if (platform === 'mp-weixin') {
// 微信专属逻辑
}
// #endif
区别:条件编译会删除代码,运行时判断不会。优先用条件编译,只有需要动态逻辑时才用运行时变量。
10. 避免常见陷阱与最佳实践
- 不要嵌套条件编译:UniApp 不支持嵌套
#ifdef,需用逻辑运算符组合。 - 保持平台标识统一:建议团队约定只用
MP-WEIXIN、H5、APP-PLUS等标准值。 - 抽离平台差异到单独文件:如
platform/mp-weixin.js,主逻辑通过条件编译引入,提升可读性。 - 编译后检查:用
npm run build:mp-weixin后查看 dist 目录,确认无关代码已被移除。 - 注释清晰:在条件编译块上方写明“为什么需要此平台差异”,方便后续维护。
总结
条件编译是 UniApp 多端开发的利器,核心思想是把平台差异收敛到编译阶段,让运行时逻辑尽可能统一。掌握这 10 个技巧后,你可以自信地在一个代码库中管理微信、H5、App 等多端,既不用写大量 if-else,也不用维护多个分支。记住:能编译时解决的,绝不留给运行时。优雅处理多端差异,从用好条件编译开始。
未经允许不得转载:任鹏个人博客 » UniApp 条件编译详解:优雅处理多端差异的 10 个技巧


朋友圈点赞图在线生成源码