当前位置: 首页 > article >正文

uni-app 玩转条件编译:自定义平台的条件编译实战详解

一. 条件编译支持的场景

uni-app 的条件编译能支持以下几种场景,具体如图所示:

1. API 的条件编译

简言之,同一功能实现,可能有不同的逻辑处理,比如:在 js 文件中,或者在 Vue 文件中的 script 代码中有不同的逻辑处理方式,使用方式如下:

// #ifdef  %PLATFORM%
该平台特有的API实现;
// #endif

2. 组件的条件编译

在 template 模版中,可能会在不同的平台展示不同的组件,或者是展示效果不同,或者是在某一平台不需要展示,使用方式如下:

<!--  #ifdef  %PLATFORM% -->
该平台特有的组件
<!--  #endif -->

3. 样式的条件编译

在不同的平台下有差异性的样式处理,使用方式如下:

/*  #ifdef  %PLATFORM%  */
该平台特有的样式
/*  #endif  */

4. pages.json 的条件编译

不同平台下的特有功能,以及小程序平台的分包,都可以通过 pages.json 的条件编译来更好地实现。这样,就不会在其它平台产生多余的资源,进而减小包体积。

例如:在 pages.json 中配置 pages 页面路由,在 H5 平台下编译 “测试 1” 页面,在微信小程序页面下编译 “测试 2” 页面

"pages": [
    // #ifdef H5
    {
      "path": "pages/test1",
      "style": {
        "navigationBarTitleText": "测试1"
      }
    },
    // #endif
    // #ifdef MP-WEIXIN
    {
      "path": "pages/test2",
      "style": {
        "navigationBarTitleText": "测试2"
      }
    },
    // #endif
]

特别注意:json 的条件编译,一定要注意最后","分隔符的所属问题,不能有多余的逗号,可能会出现异常情况,导致编译失败!

5. static 目录的条件编译

在不同平台,引用的静态资源可能也存在差异,通过 static 的条件编译可以解决此问题,static 目录下新建不同平台的专有目录,目录名称均为小写,专有目录下的静态资源只有在特定平台才会编译进去。

如以下目录结构,a.png 只有在微信小程序平台才会编译进去,b.png 在所有平台都会被编译,合理的利用 static 目录的条件编译能够大大的减小包体积,在微信小程序的分包实践中尤为重要!

┌─static
│  ├─mp-weixin
│  │  └─a.png
│  └─b.png
├─main.js
├─App.vue
├─manifest.json
└─pages.json

二. 注意事项

关于条件编译,有以下几个注意事项需要在编程的过程中重点关注一下:

  1. 条件编译 APP-PLUS 包含 APP-NVUE 和 APP-VUE ;

  2. 对于未定义平台名称,可能是名称写错了,也可能是低版本 HBuilderX 没有这个平台,此时的条件编译,#ifdef 中的代码不会生效,而 #ifndef 中的代码会生效;

  3. 使用条件编译请保证编译前和编译后文件的语法正确性,即要保障无论条件编译是否生效都能通过语法校验。比如:json 文件中不能有多余的逗号,js 中不能重复导入;

  4. Android 和 iOS 平台不支持通过条件编译来区分,如果需要区分 Android、iOS 平台,请通过调用 uni.getSystemInfo 来获取平台信息。支持 ifiosifAndroid 代码块,可方便编写判断。

三. 自定义条件编译平台

1. 背景(我为什么要进行自定义平台)

在开发 Web 时,可能有时候需要将同一套代码编译发布到不同的站点,比如多个不同的微信 h5 站,这些站点可能有不同的差异性处理。在开发小程序时,也经常有扩展小程序平台,比如同一套代码,我需要发布到多个小程序,可能这些小程序之间少许有些差异。因此,uni-app 通过在 package.json 文件中增加 uni-app 扩展节点,可实现自定义条件编译平台。

在我之前开发的实际项目中,同一套代码需要部署多个平台,大概有 10 个平台,而且这几个平台可能有 90% 以上的代码是相同的,因此我就没有必要重新开发一套代码了。这多个平台的含义是:在微信小程序有多个平台,在 H5 网站有多个平台,可能在 APP 中也有多个平台,在这些平台之间,可能有或多或少的差异,比如:

  • 功能的差异性,页面展示不同,tabbar 数量等

  • 请求 API 的差异性,对应的后端服务 API 不同

  • 全局变量的差异性,主题配色变量,默认语言等

因此,以上这些差异就会要求在代码中处理不同平台之间的差异性,以下是我的实际项目中的自定义平台:

除此之外,还有两个 APP 平台,但是目前 uni-app 不支持自定义 APP 的基准平台!

如何增加 uni-app 扩展节点,总结一下有以下几个步骤可以快速完成一个全新平台的编译:

  • 声明配置,添加新平台

  • 在代码中使用新平台条件编译

  • 编译到新平台

2. 第一步: 声明配置,添加新平台

在 package.json 中添加 uni-app 节点,添加以下配置,使新定义的平台生效:

   "uni-app": {
    "scripts": {
      "custom-h5": {
        "title": "自定义H5平台",
      "browser": "chrome",
        "env": {
          "UNI_PLATFORM": "h5"
        },
        "define": {
          "CUSTOM-H5": true
        }
      },
      "custom-mp": {
        "title": "自定义小程序平台",
        "env": {
          "UNI_PLATFORM": "mp-weixin"
        },
        "define": {
          "CUSTOM-MP": true
        }
      }
    }
  }

参数说明:

正确的结构就是如上所示,下面说一下这几个参数的具体含义

  • title:自定义扩展名称, 在 HBuilderX 中会显示在 运行/发行 菜单中

  • browser:运行到的目标浏览器,仅当 UNI_PLATFORM 为 h5 时有效

  • env:环境变量
    • UNI_PLATFORM:基准平台

    • MY_TEST:其他自定义环境变量

  • define:自定义条件编译
    • CUSTOM-H5:自定义条件编译常量,建议为大写

注意事项:

  • 只能扩展 web 和小程序平台,不能扩展 app 平台。并且扩展小程序平台时只能基于指定的基准平台扩展子平台,不能扩展基准平台。也就是说 UNI_PLATFORM 仅支持填写 uni-app 默认支持的基准平台,目前仅限如下枚举值:h5mp-weixinmp-alipaymp-baidump-toutiaomp-qq

  • browser 仅在 UNI_PLATFORM 为 h5 时有效,目前仅限如下枚举值:chrome、firefox、ie、edge、safari、hbuilderx。

  • package.json 文件中不允许出现注释,否则扩展配置无效。

3. 第二步:在代码中使用条件编译

接下来,可以在代码里使用自定义的条件编译,为这个新平台编写专用代码:

// 新的自定义微信小程序平台
// #ifdef CUSTOM-MP
/**
 * 微信小程序 代码
 */
// #endif

// 新的自定义H5平台
// #ifdef CUSTOM-H5
/**
 * H5 代码
 */
// #endif

4. 第三步:编译到新平台

运行时可以执行面向新平台的编译运行,发行时可以执行面向新平台的编译发行。如下图所示,我们点击运行和发行,已经都有了我们刚才已经自定义好的平台名称。

四. 总结

关于你是否需要自定义平台,关键在于项目里复用的代码多还是个性的代码多,如果都是复用的代码多,并且对应的服务端是一致的,所以仍然可以自定义平台多端部署,而个性的代码放到不同平台的目录下,进行差异化维护。

五. 资源文档

  • uni-app 组件使用手册

  • uni-app API 使用手册

  • uni-app 条件编译处理多端差异

  • package.json 扩展 uni-app 属性

  • vue.config.js 说明


http://www.kler.cn/a/405725.html

相关文章:

  • 移动语义和拷贝语义区别、智能指针
  • 微信小程序组件详解:text 和 rich-text 组件的基本用法
  • 【ArcGIS微课1000例】0132:从多个GIS视角认识与攀登珠穆朗玛峰
  • SpringCloud多机部署,负载均衡-LoadBalance
  • 科研实验室的数字化转型:Spring Boot系统
  • 用指针函数寻找数组中的最大值与次大值
  • 微软 Ignite 2024 大会
  • CSS查缺补漏(补充上一条)
  • [C#] Bgr24彩色位图转为Gray8灰度位图的跨平台SIMD硬件加速向量算法
  • JDK1.8中JVM堆内存等参数配置
  • 微信小程序自定义图片预览操作按钮(解决api预览时不能删除提交服务器等自定义操作)
  • 大数据新视界 -- 大数据大厂之 Impala 性能优化:跨数据中心环境下的挑战与对策(上)(27 / 30)
  • 嵌入式系统与OpenCV
  • FIFO和LRU算法实现操作系统中主存管理
  • Vue.js 性能优化指南:掌握 keep-alive 的使用技巧
  • 面向对象-接口的使用
  • Spring框架特性及包下载(Java EE 学习笔记04)
  • SpringBoot与knife4j的整合使用
  • Spark RDD 的宽依赖和窄依赖
  • 2024年亚太数学建模竞赛问题C宠物产业及相关产业发展分析与对策
  • CEF127编译指南 Windows篇-安装Git和Python(三)
  • C语言深度剖析:定义与声明
  • Go-RPC关键指标分析与企业实践
  • Unity 编辑器下 Android 平台 Addressable 加载模型粉红色,类似材质丢失
  • 金融量化交易模型的突破与前景分析
  • PostGIS创建空间数据库步骤