Appearance
跨端兼容
qinjs 已将常用的组件、API封装到框架中,开发者按照 qinjs 规范开发即可保证多平台兼容,大部分业务均可直接满足。
但每个平台有自己的一些特性,因此会存在一些无法跨平台的情况。
- 大量写 if else,会造成代码执行性能低下和管理混乱。
- 编译到不同的工程后二次修改,会让后续升级变的很麻烦。
- 为每个平台重写,明明主业务逻辑又一样
在 C 语言中,通过 #ifdef、#ifndef 的方式,为 windows、mac 等不同 os 编译不同的代码。 qinjs 参考这个思路,为 qinjs 提供了条件编译手段,在一个工程里优雅的完成了平台个性化实现。
条件编译
条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。
写法: 以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。
#ifdef:if defined 仅在某平台存在#ifndef:if not defined 除了某平台均存在%PLATFORM%:平台名称
| 条件编译写法 | 说明 |
|---|---|
#ifdef APP-PLUS 需条件编译的代码 #endif | 仅出现在 App 平台下的代码 |
#ifndef H5 需条件编译的代码 #endif | 除了 H5 平台,其它平台均存在的代码(注意if后面有个n) |
#ifdef H5 || WX 需条件编译的代码 #endif | 在 H5 平台或微信小程序平台存在的代码(这里只有||,不可能出现&&,因为没有交集) |
%PLATFORM% 可取值如下:
| 值 | 生效条件 | 版本支持 |
|---|---|---|
| H5 | H5(推荐使用 WEB) | |
| WX | 微信小程序 | |
| XHS | 小红书小程序 | |
| TT | 抖音小程序 | |
| KS | 快手小程序 |
支持的文件
- .vue/.nvue/.uvue
- .js/.uts
- .css
- pages.json
- 各预编译语言文件,如:.scss、.less、.stylus、.ts、.pug
注意:
条件编译是利用注释实现的,在不同语法里注释写法不一样,js/uts使用
// 注释、css 使用/* 注释 */、vue/nvue/uvue 模板里使用<!-- 注释 -->;条件编译APP-PLUS包含APP-NVUE和APP-VUE,APP-PLUS-NVUE和APP-NVUE没什么区别,为了简写后面出了APP-NVUE ;
对于未定义平台名称,可能是名称写错了,也可能是低版本HBuilderX还不认识这个平台。此时的条件编译,
#ifdef中的代码不会生效,而#ifndef中的代码会生效;使用条件编译请保证
编译前和编译后文件的语法正确性,即要保障无论条件编译是否生效都能通过语法校验。比如:json文件中不能有多余的逗号,js中不能重复导入;JSON 错误示例
json{ "key": "a", // #ifdef WX "key": "b" // #endif }{ "key": "a", // #ifdef WX "key": "b" // #endif }JSON 正确示例
json{ "key": "a" // #ifdef WX ,"key": "b" // #endif }{ "key": "a" // #ifdef WX ,"key": "b" // #endif }JS 错误示例
js// #ifdef WX import a from 'a/wx' // #endif // #ifndef WX import a from 'a/index' // #endif// #ifdef WX import a from 'a/wx' // #endif // #ifndef WX import a from 'a/index' // #endifJS 正确示例
js// #ifdef WX import a as aWx from 'a/wx' // #endif // #ifndef WX import a as aIndex from 'a/index' // #endif var a // #ifdef WX a = aWx // #endif // #ifndef WX a = aIndex // #endif// #ifdef WX import a as aWx from 'a/wx' // #endif // #ifndef WX import a as aIndex from 'a/index' // #endif var a // #ifdef WX a = aWx // #endif // #ifndef WX a = aIndex // #endifVUE3需要在项目的manifest.json文件根节点配置"vueVersion" : "3";
qinjs 还支持 taro3 的平台编译规则
|文件名称 |平台 | |:-: |:-: |:-: | |list.h5.vue |H5 平台编译 | | |list.wx.vue |微信小程序 | | |list.xhx.vue |小红书小程序 | | |list.tt.vue |抖音小程序 | | |list.ks.vue |快手小程序 | |
API 的条件编译
// #ifdef %PLATFORM%
平台特有的API实现
// #endif示例,如下代码仅在 App 下出现:

示例,如下代码不会在 H5 平台上出现:

除了支持单个平台的条件编译外,还支持多平台同时编译,使用 || 来分隔平台名称。
示例,如下代码会在 App 和 H5 平台上出现:

组件的条件编译
<!-- #ifdef %PLATFORM% -->
平台特有的组件
<!-- #endif -->示例,如下公众号关注组件仅会在微信小程序中出现:
html
<view>
<view>微信公众号关注组件</view>
<view>
<!-- uni-app未封装,但可直接使用微信原生的official-account组件-->
<!-- #ifdef WX -->
<official-account></official-account>
<!-- #endif -->
</view>
</view><view>
<view>微信公众号关注组件</view>
<view>
<!-- uni-app未封装,但可直接使用微信原生的official-account组件-->
<!-- #ifdef WX -->
<official-account></official-account>
<!-- #endif -->
</view>
</view>样式的条件编译
/* #ifdef %PLATFORM% */
平台特有样式
/* #endif */注意: 样式的条件编译,无论是 css 还是 sass/scss/less/stylus 等预编译语言中,必须使用 /*注释*/ 的写法。
正确写法

错误写法

pages.json 的条件编译
下面的页面,只有运行至 App 时才会编译进去。

不同平台下的特有功能,以及小程序平台的分包,都可以通过 pages.json 的条件编译来更好地实现。这样,就不会在其它平台产生多余的资源,进而减小包体积。
json的条件编译,如不同平台的key名称相同,cli项目下开发者自己安装的校验器会报错,需自行关闭这些校验器对json相同key的校验规则。如果使用HBuilderX的校验器,无需在意此问题,HBuilderX的语法校验器为此优化过。
static 目录的条件编译@static
在不同平台,引用的静态资源可能也存在差异,通过 static 的条件编译可以解决此问题,static 目录下新建不同平台的专有目录,目录名称均为小写,
| 目录名称 | 说明 | 版本支持 |
|---|---|---|
| h5 | H5 | |
| wx | 微信小程序 | |
| xhx | 小红书小程序 | |
| tt | 抖音小程序 | |
| ks | 快手小程序 |
专有目录下的静态资源只有在特定平台才会编译进去。
如以下目录结构,a.png 只有在微信小程序平台才会编译进去,b.png 在所有平台都会被编译。
shell
┌─static
│ ├─wx
│ │ └─a.png
│ └─b.png
├─main.js
├─App.vue
├─manifest.json
└─pages.json┌─static
│ ├─wx
│ │ └─a.png
│ └─b.png
├─main.js
├─App.vue
├─manifest.json
└─pages.json整体目录条件编译
如果想把各平台的页面文件更彻底的分开,也可以在uni-app项目根目录创建platforms目录,然后在下面进一步创建app-plus、wx等子目录,存放不同平台的文件。
注意
platforms目录下只支持放置页面文件(即页面vue文件),如果需要对其他资源条件编译,建议使用static 目录的条件编译。