0%

Hello uni-app

最后更新于 2020-2-20, 信息出入请以 uni-app official document 为准
为了保证信息有效性, 大量使用了文字链接关联官方文档的相关内容


( 图片源 uni-app official document )

开局一张图,内容开始编。

近期接手维护一个基于 uni-app 框架开发的项目,故笔墨伺候,简单做下功课。

以下内容对于未听说过或者未使用过 uni-app的前端“熟练工”相对比较友好些,内容有误,敬请指正。

uni-app 是一个使用 Vue.js 开发全平台(App,小程序,Web/H5)前端应用的框架, 由”为开发者而生的” W3C 成员及 HTML5 中国产业联盟的发起单位,数字天堂(北京)网络技术有限公司(DCloud)出品。

uni you ni,是统一的意思.
app 当指“应用(软件)”时,按 Google 翻译以及 Apple 官方读音, 读/æp/,而非 /eɪ̯.pʰiː.pʰiː/

已知全貌,准予置评。 🙈🙈🙈

开始吧…

已有技术储备

摘几点规范

  1. 页面文件遵循Vue 单文件组件 (SFC) 规范, 见 Vue 官方文档关于单文件组件介绍

  2. 组件的标签靠近了微信小程序的规范,不推荐使用 HTML 标签,但如果开发者使用了 divHTML 标签,在编译到非 H5 平台时也会被编译器转换为 viewuni-app 组件标签,同时包括 css 里的元素选择器也会同时转译。但为了管理方便、策略统一,建议使用 uni-app 组件标签

  3. 为了兼容多端,建议使用 flex 布局 , 样式单位使用 rpx 自适应单位

  4. 选择 uni-app 框架的目的自然是为了满足跨端需求,抑或是为了项目将来可能出现的跨端需求时尽可能降低开发成本, 因此,应该尽可能避免使用各平台的原生 api, 比如不要使用 H5 平台浏览器自带的对象,比如 documentwindowlocalstoragecookie等,更不要使用像 jQuery 等依赖这些浏览器对象的实现的框架, 不管是 App 还是各家 小程序, 快应用均不支持.
    因此, 建议拥抱使用 uni-app 提供的 api, uniapi是足够完成业务的,将各平台的 api 交由 uni-app 框架内部统一去适配处理. 事实上, uniapi 在编译到各个平台运行时就是会转为个平台对应的原始api 的.

记几点知晓

  1. 目测 uni-app 并没有同步更新 CLI官方 IDE HbuilderX 中使用的 uni-app 版本, 如需享有 uni-app 各种新版本升级带来的全方位提升以及 uni-app 项目友好的开发体验, 还是须拥抱 HbuilderX IDE. (说到此, 笔者着实受限于目前 HbuilderXLinux 版本, 只得默默使用 CLI 开发)

  2. uni-app 除了支持 ECMAScript 的 JS API 外, 支持了靠近微信小程序 API扩展 API,将前缀 wx 替换为 uni

  3. uni-app 在支持 Vue 的基础上( 目前并未 100% 全面支持,详请可下文注意事项中关于Vue的说明 ), 靠近了小程序,补充了 应用的生命周期和页面的生命周期

  4. uni-app 路由方式同样靠近了微信小程序,在 pages.json 中配置路由页面, 在页面生命周期中的 onLoad 函数中获取路由携带的参数, 详见 uni-app路由, 当然开发者如需保持与 vue-router 一致的开发体验,可以尝试在 uni-app 插件市场 甄别合适插件择优慎用.

  5. uni-app 中的数据绑定, 则遵循了 Vue 2.0 的写法实现, 不支持微信小程序的数据绑定写法

    1
    2
    3
    4
    5
    6
    <!-- ❌ 微信小程序的数据绑定方式是无效的-->
    <view id="item-{{id}}"></view>

    <!-- ⭕ 请使用 Vue 的数据绑定方式 -->
    <view v-bind:id="'item-' + id "></view>
    <view :id="'item-' + id "></view>

跨端开发

条件编译

“编译时” 条件编译

  1. 代码的条件编译

    C 语言中,通过 #ifdef#ifndef 的方式,为 windowsmac 等不同 os 编译不同的代码。
    uni-app 参考这个思路,同样提供了条件编译的方式

    写法:

    #ifdef#ifndef%PLATFORM% 开头,以 #endif 结尾。

    • #ifdef:if defined 仅在某平台存在
    • #ifndef:if not defined 除了某平台均存在
    • %PLATFORM%:平台名称

    支持的文件:

    • *.vue
    • *.js
    • *.css
    • pages.json
    • 各预编译语言文件,如:*.scss*.less*.stylus*.ts*.pug

    注意:

    • 条件编译是利用注释实现的,在不同语法里注释写法不一样,如: js 使用 // 注释css 使用 /* 注释 */vue/nvue 模板里使用 <!-- 注释 -->

    • pages.json 的条件编译,如不同平台的 key 名称相同,cli 项目下开发者自己安装的校验器会报错,需自行关闭这些校验器对 json 相同 key 的校验规则。

    %PLATFORM%值:

    平台
    APP-PLUS App
    APP-PLUS-NVUE App nvue
    H5 H5
    MP-WEIXIN 微信小程序
    MP-ALIPAY 支付宝小程序
    MP-BAIDU 百度小程序
    MP-TOUTIAO 头条小程序
    MP-QQ QQ 小程序(目前仅 cli 版支持)
    MP 微信小程序/支付宝小程序/百度小程序/头条小程序/QQ 小程序

    示例:

    1
    2
    3
    <!--  #ifdef  %PLATFORM% -->
    <view></view>
    <!-- #endif -->
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // #ifdef  %PLATFORM%
    console.log("hello uni app");
    // #endif

    // #ifdef %PLATFORM%
    {
    "path":"pages/home/home",
    "style":{
    "navigationBarTitleText":"Hell uni-app"
    }
    }
    // #endif
    1
    2
    3
    4
    5
    /*  #ifdef  %PLATFORM%  */
    view {
    display: none;
    }
    /* #endif */
  2. static 资源文件的条件编译

    static 目录下创建不同名称的专有目录(目录名称同 %PLATFORM% 值,但字母须均为小写),
    专有目录下的静态资源只有在特定平台才会编译进去。

    1
    2
    3
    4
    5
    6
    ...
    ┌─static
    │ ├─mp-weixin
    │ │ └─a.png
    │ └─b.png
    ...
  3. 页面文件的条件编译

    可以在项目根目录创建 platforms 目录,然后创建对应不同平台的APP-PLUSMP-WEIXIN、…等子目录,存放对应不同平台的页面文件

“运行时” 判断:

  1. api 获取平台信息

    1
    uni.getSystemInfoSync().platform; // 输出 android | ios | devtools
  2. 在“编译时”的条件编译中自行定义一个变量,赋不同值,来供后续在”运行时“代码中,获取所需具体的环境信息。

异常可能性排查指南

传送门系列, 实战爬坑必备

各端兼容适配指北

传送门系列, 实战爬坑必备

各端规范

传送门系列, 各平台官方

其他

传送门系列, 实战爬坑必备

注意事项

Vue.js

  1. uni-app 在发布到 H5 时支持所有 Vue 的语法

  2. uni-app 发布到 App小程序 时,无法实现全部 Vue 语法

  3. 此外, uni-app 老版本(即 manifest.json"usingComponents":false),支持 Vue部分模板语法

    1. 不支持部分复杂的 JavaScript 渲染表达式
    2. 不支持过滤器

    那么何为老版本,找了下社区文档,从一篇名为”uni-app 新老编译模式差异说明”的帖子中可以了解到 1.8版本 之前的为老版本,而从 1.8版本 起新增了编译模式: 自定义组件模式 ,原来的老版本的编译模式则命名为 template模板模式 ,新版本向下兼容同时支持了两种编译模式.那么后续创建项目需要选择编译模式时, 当然优先选择对 Vue 支持度更高,性能更佳的新模式:自定义组件模式.

    这篇帖子非常详细地介绍了如何切换编译模式, 非自定义组件模式升级为自定义组件模式注意, 不同编译模式支持的 Vue 语法差异, 详情可移步至“uni-app 新老编译模式差异说明”

  4. uni-app 全局变量的几种实现方式: 公用模块, 挂载Vue.prototype, globalData, Vuex 各有千秋, 其中 Vuex 的数据响应机制最适合处理变量.

    但是需要注意的的是, 在 uni-app 中使用 Weex, 也就是文件名为 .nvue 时, 不支持 挂载Vue.prototype 的方式, 而且 nvue ( native vue ) 是从 HBuilderX 2.2.5 起,也才支持 Vuex

    如果希望 .vue.nvue 复用一些方法的话,目前只能推荐采用公用模块的方案,分别在 .vue.nvue 文件中引入。

  5. H5 端不支持在自定义组件上使用 ClassStyle 绑定, 也不支持 Vue 的 Class 与 Style 绑定 中的 classObjectstyleObject 语法

  6. H5 平台 使用 v-for 循环整数时和其他平台存在差异,如 v-for="(item, index) in 10" 中,H5 平台 item1 开始,其他平台 item0 开始,可使用第二个参数 index 来保证一致。

  7. H5 平台 循环对象时不支持第三个参数,如 v-for="(value, name, index) in object" 中, index 参数是不支持的。

  8. 完整支持 Vuedata 属性, 计算属性, 条件渲染, 列表渲染, 表单控件绑定

  9. 几乎全支持 Vue 的事件处理器

    1. 为兼容各端,事件需使用 v-on@ 的方式绑定,请勿使用小程序端的 bindcatch 进行事件绑定.
    2. 事件修饰符: .prevent, .self, .once, .capture, .passive 仅在 H5 平台支持, .stop 全平台均支持, 阻止事件冒泡,在 H5 端**使用时同时阻止事件的默认行为, uni-app专注移动端,未支持键盘事件,因此不支持按键修饰符。
  10. v-html: 目前只支持 H5 端和在 uni-app V3 版本编译模式下的 App 端, 社区有跨端的富文本处理方案

  11. 除了支持 Vue “组件三步法”:引入, 注册, 使用 外, uni-app 2.5.0+ 版本支持在 page.json中配置组件,配置完成后, 无需引入, 无需注册, 即可直接使用, 详见 easycom

  12. H5 端不支持如下组件特性:

    • Slots(scoped 暂时还没做支持)
    • 动态组件
    • 异步组件
    • inline-template
    • X-Templates
    • keep-alive
    • transition (可使用 animationCSS 动画替代)
    • 老版本以及新版中非自定义组件编译模式不支持在组件上定义 click 等原生事件、不支持 v-show(可用 v-if 代替), 也不支持以定义 class 的方式来实现 style 样式属性(例:<card class="class-name"> </card> 样式是不会生效的)
    • 老版本以及新版中非自定义组件编译模式在组件里使用 slot 嵌套的其他组件时不支持 v-for
  13. main.js 入口文件中, Vue.component注册全局组件时第一个参数必须是静态的字符串, .nvue 页面暂支持全局组件,另外,关于自定义组件的命名, 除了不能使用标准的 HTMLSVG 标签名外, 也不能使用 uni-app 中的 保留关键字,附上列表.

Weex(nvue)

传送门
使用 Weex/nvue 注意事项

HTML5+

传送门
使用 HTML5+ 注意事项

开始实操项目, Enjoy!

其他的内容例如 uni-app 框架的 配置,框架接口组件 以及 API, 其实与 微信小程序 大同小异, 拥有了小程序原生开发技术, 直接在实践中按需查阅即可。

官方推荐

个人实践