UniApp 条件编译详解:优雅处理多端差异的 10 个技巧

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-WEIXINMP-ALIPAYMP-BAIDUH5APP-PLUSAPP-VUEAPP-NVUE。注意 APP-PLUS 代表整个 App 平台,而 APP-VUEAPP-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-WEIXINH5APP-PLUS 等标准值。
  • 抽离平台差异到单独文件:如 platform/mp-weixin.js,主逻辑通过条件编译引入,提升可读性。
  • 编译后检查:用 npm run build:mp-weixin 后查看 dist 目录,确认无关代码已被移除。
  • 注释清晰:在条件编译块上方写明“为什么需要此平台差异”,方便后续维护。

总结

条件编译是 UniApp 多端开发的利器,核心思想是把平台差异收敛到编译阶段,让运行时逻辑尽可能统一。掌握这 10 个技巧后,你可以自信地在一个代码库中管理微信、H5、App 等多端,既不用写大量 if-else,也不用维护多个分支。记住:能编译时解决的,绝不留给运行时。优雅处理多端差异,从用好条件编译开始。

未经允许不得转载:任鹏个人博客 » UniApp 条件编译详解:优雅处理多端差异的 10 个技巧

赞 (0) 打赏

评论 0

取消
  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏