# uni-app

# uni-app介绍

uni-app 是一个使用 Vue.js(opens new window)开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉/淘宝)、快应用等多个平台。

# uni-app选型

# 跨端开发框架对比

多端开发框架对比横评,参考:https://juejin.im/post/5e8e8d5a6fb9a03c6d3d9f42

总结: 跨端框架是一个重投入工作,在各框架的1年多的比拼中,很多框架因为投入不足而逐渐被开发者放弃,uni-app和taro依靠持续的大力度投入,成为了市场主流。

  1. 如果你熟悉React,不懂Vue.js,推荐Taro;
  2. 如果你熟悉Vue.js,则推荐 uni-app;
  3. 如果你的业务涉及多端,更推荐 uni-app;
  4. 如果你希望通过 serverless 方案快速上线业务,推荐 uni-app。

# App,flutter、react native等App跨平台框架对比

参考:https://ask.dcloud.net.cn/article/36083

技术学习成本和难度

  • rn:要求开发者学习react,要求精通flex布局,要求原生开发协作。
  • flutter:要求开发者学习dart,了解dart和flutter的API、要求精通flex布局,要求原生开发协作。
  • weex:已经内嵌到uni-app中,就不单独提了。
  • uni-app:要求开发者学习vue,了解小程序。 很明显uni-app的学习成本太低了,它没有附加专有技术,全部使用公共技术。

总结

总结flutter与uni-app的比较:

  • flutter与uni-app的相对优势:

    性能好一丢丢。比rn有优势,但比拥有bindingx和wxs的uni-app,在实际开发中没有很明显的差距。

  • flutter与uni-app的相对劣势:

    需要原生协作,维护3套代码,无法有效降低开发成本,提升开发效率

    嵌套地狱,代码难看难维护

    不支持热更新

    目前质量和成熟度很低

    原生可视控件融合不好,比如webview、video、map

    ui库不适合国情

    学习成本高

    应用场景有限,dart未来扑朔迷离

总结rn和uni-app的比较

  • rn与uni-app的相对优势:

    rn的坑虽然比weex的少,但uni-app已经填了weex的很多坑。这方面差别不大。

    rn的生态虽然比weex丰富。但uni-app是反过来的,uni-app的国内应用生态丰富度超过了rn。

    rn是纯单页的,嵌入原生App比较灵活。而uni-app是应用整体的概念,如果要内嵌入其他原生应用的话,要求原生应用内嵌uni-app应用整体进来。即集成uni小程序sdk (opens new window)

  • rn与uni-app的相对劣势:

    需要原生协作,维护3套代码,无法有效降低开发成本,提升开发效率

    不支持小程序,发布到h5也无法直接发

    性能不如uni-app

    国内的插件生态不如uni-app丰富

    ui库不适合国情,learn once,write anywhere

    学习成本高,用人成本高,不利于开发商降低开发成本

    rn是纯单页应用,如果一个应用的页面很多,用rn写会很崩溃,变量污染和干扰严重。而weex/uni-app支持多页面,页面之间上下文隔离,写页面较多的大型应用更合适

另外react在中国的市场占有率远不如vue。这也是中国与国外不同的特色情况。

# 快速创建并运行uni-app项目

uni-app支持通过 可视化界面、vue-cli命令行(opens new window) (opens new window)两种方式快速创建项目。本文档写关于hbuilder X如何创建项目也建议用可视化界面创建项目,命令行自行查看官方文档

# 创建uni-app

在点击工具栏里的文件 -> 新建 -> 项目: 选择uni-app类型,输入工程名,选择模板,点击创建,即可成功创建。

uni-app自带的模板有 Hello uni-app ,是官方的组件和API示例。还有一个重要模板是 uni ui项目模板,日常开发推荐使用该模板,已内置大量常用组件。

# 运行uni-app

浏览器运行:进入hello-uniapp项目,点击工具栏的运行 -> 运行到浏览器 -> 选择浏览器,即可在浏览器里面体验uni-app 的 H5 版。

运行App到手机或模拟器:连接手机,开启USB调试,进入hello-uniapp项目,点击工具栏的运行 -> 真机运行 -> 选择运行的设备,即可在该设备里面体验uni-app。 如手机无法识别,请点击菜单运行-运行到手机或模拟器-真机运行常见故障排查指南。 注意目前开发App也需要安装微信开发者工具。

在微信开发者工具里运行:进入hello-uniapp项目,点击工具栏的运行 -> 运行到小程序模拟器 -> 微信开发者工具,即可在微信开发者工具里面体验uni-app。

一次使用,需要先配置小程序ide的相关路径,才能运行成功。如下图,需在输入框输入微信开发者工具的安装路径。 若HBuilderX不能正常启动微信开发者工具,需要开发者手动启动,然后将uni-app生成小程序工程的路径拷贝到微信开发者工具里面,在HBuilderX里面开发,在微信开发者工具里面就可看到实时的效果。uni-app默认把项目编译到根目录的unpackage目录。

# 开发入门

# uni-app对比vue开发变化

# 组件/标签的变化

  • 以前是html标签,比如<div>,现在是小程序组件,比如<view>
  • 那么标签和组件有什么区别,不都是用尖括号包围起来一段英文吗?
  • 其实标签是老的概念,标签属于浏览器内置的东西。但组件,是可以自由扩展的。
  • 类似你可以把一段js封装成函数或模块,你也可以把一个ui控件封装成一个组件。
  • uni-app参考小程序规范,提供了一批内置组件。
  • 下为html标签和uni-app内置组件的映射表:

div 改成 view (opens new window)

span、font 改成 text (opens new window)

a 改成 navigator (opens new window)

img 改成 image (opens new window)

input (opens new window) 仅仅是输入框。 原html规范中input不仅是输入框,还有radio、checkbox、时间、日期、文件选择功能。在uni-app和小程序规范中,input仅仅是输入框。其他功能uni-app有单独的组件或API:radio组件 (opens new window)checkbox组件 (opens new window)、时间选择、日期选择、图片选择、视频选择、多媒体文件选择(含图片视频)、通用文件选择。

form、button、label、textarea、canvas、video 这些还在。

select 改成 picker

iframe 改成 web-view

ul、li没有了,都用view替代。做列表一般使用uList组件

audio 不再推荐使用,改成api方式,背景音频api文档

其实老的HTML标签也可以在uni-app里使用,uni-app编译器会在编译时把老标签转为新标签,比如把div编译成view。但不推荐这种用法,调试H5端时容易混乱。

除了改动外,新增了一批手机端常用的新组件

scroll-view 可区域滚动视图容器

swiper 可滑动区域视图容器

icon 图标

rich-text 富文本(不可执行js,但可渲染各种文字格式和图片)

progress 进度条

slider 滑块指示器

switch 开关选择器

camera 相机

live-player 直播

map 地图

cover-view 可覆盖原生组件的视图容器 cover-view需要多强调几句,uni-app的非h5端的video、map、canvas、textarea是原生组件,层级高于其他组件。如需覆盖原生组件,则需要使用cover-view组件。详见层级介绍

# js的变化

js的变化,分为运行环境变化、数据绑定模式变化、api变化3部分。

运行环境从浏览器变成v8引擎

标准js语法和api都支持,比如if、for、settimeout、indexOf等。

但浏览器专用的window、document、navigator、location对象,包括cookie等存储,只有在浏览器中才有,app和小程序都不支持。

可能有些人以为js等于浏览器里的js。其实js是ECMAScript组织管理的,浏览器中的js是w3c组织基于js规范补充了window、document、navigator、location等专用对象。

在uni-app的各个端中,除了h5端,其他端的js都运行在一个独立的v8引擎下,不是在浏览器中,所以浏览器的对象无法使用。

# css的变化

标准的css基本都是支持的。

选择器有2个变化:*选择器不支持;元素选择器里没有body,改为了page。微信小程序即是如此。复制代码page{ }

单位方面,px无法动态适应不同宽度的屏幕,rem无法用于nvue/weex。如果想使用根据屏幕宽度自适应的单位,推荐使用rpx,全端支持。 尺寸单位文档

uni-app推荐使用flex布局,这个布局思路和传统流式布局有点区别。但flex的特色在于,不管是什么技术都支持这种排版,web、小程序/快应用、weex/rn、原生的iOS、Android开发,全都支持flex。它是通吃所有端的新一代布局方案。

uni-app的vue文件里支持所有web排版方式,不管是流式还是flex。但nvue里,只支持flex,因为它在app端是使用原生排版引擎渲染的。

注意css里背景图和字体文件,尽量不要大于40k,因为会影响性能。在小程序端,如果要大于40k,需放到服务器侧远程引用或base64后引入,不能放到本地作为独立文件引用。

# 路由变化

在vue项目中需要单独引入vue-router来配置使用路由,而在uni-app中每个可显示的页面,都必须在 pages.json 中注册。

路由注册

pages节点的第一项为应用入口页(即首页)

{
  "pages": [{
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "首页",//设置页面标题文字
        "enablePullDownRefresh":true//开启下拉刷新
      }
    },
    ...
  ]
}
1
2
3
4
5
6
7
8
9
10
11

路由跳转

uni-app 有两种页面路由跳转方式:使用navigator (opens new window)组件跳转、调用API (opens new window)跳转。

路由方式 页面栈表现 触发时机
打开新页面 新页面入栈保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面。 调用 API uni.navigateTo (opens new window)、使用组件<navigatoropen-type="navigate"/> (opens new window)
页面重定向 当前页面出栈,新页面入栈关闭当前页面,跳转到应用内的某个页面。 调用 API uni.redirectTo、使用组件 <navigator open-type="redirectTo"/> (opens new window)
页面返回 页面不断出栈,直到目标返回页关闭当前页面,返回上一页面或多级页面。可通过 getCurrentPages() 获取当前的页面栈,决定需要返回几层。 调用 API uni.navigateBack (opens new window)、使用组件 <navigator open-type="navigateBack"/> (opens new window)、用户按左上角返回按钮、安卓用户点击物理back按键
Tab 切换 页面全部出栈,只留下新的 Tab 页面跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面。 调用 API uni.navigateBack (opens new window)、使用组件 <navigator open-type="navigateBack"/> (opens new window)、用户按左上角返回按钮、安卓用户点击物理back按键
重加载 页面全部出栈,只留下新的页面关闭所有页面,打开到应用内的某个页面 调用 API uni.reLaunch (opens new window)、使用组件 <navigator open-type="reLaunch"/> (opens new window)

栗子

//在起始页面跳转到test.vue页面并传递参数
uni.navigateTo({
	url: 'test?id=1&name=uniapp'
});
1
2
3
4

# 生命周期变化

uni-app 页面常用生命周期函数对比vue生命周期函数

函数名 说明 类比vue生命周期
onLoad 监听页面加载,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例 (opens new window) mounted
onShow 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
onReady 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发
onHide 监听页面隐藏
onUnload 监听页面卸载 destroyed
onResize 监听窗口尺寸变化
onPullDownRefresh 监听用户下拉动作,一般用于下拉刷新,参考示例 (opens new window)
onReachBottom onReachBottom 页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。具体见下方注意事项
onPageScroll 监听页面滚动,参数为Object

特殊:onLaunch为应用的生命周期,当uni-app 初始化完成时触发(全局只触发一次),应用生命周期仅可在App.vue中监听,在其它页面监听无效

# 开发进阶

# 原生插件使用

原生插件使用 (opens new window)

# 跨端注意

详见官网跨端注意:https://uniapp.dcloud.io/matter.html

# 条件编译

条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。 **写法:**以 #ifdef#ifndef%PLATFORM% 开头,以 #endif 结尾。

  • #ifdef:if defined 仅在某平台存在
  • #ifndef:if not defined 除了某平台均存在
  • %PLATFORM%:平台名称
条件编译写法 说明
#ifdef APP-PLUS 需条件编译的代码 #endif 仅出现在 App平台下的代码
#ifndef H5 需条件编译的代码 #endif 除了 H5 平台,其它平台均存在的代码
#ifdef H5 || MP-WEIXIN 需条件编译的代码 #endif 在 H5 平台或微信小程序平台存在的代码(这里只有||,不可能出现&&,因为没有交集)

%PLATFORM% 可取值如下:

生效条件
VUE3 HBuilderX 3.2.0+ 详情(opens new window) (opens new window)
APP-PLUS APP-PLUS App
APP-PLUS-NVUE或APP-NVUE App nvue
H5 H5 H5
MP-WEIXIN 微信小程序
MP-ALIPAY 支付宝小程序
MP-BAIDU 百度小程序
MP-TOUTIAO 字节跳动小程序
MP-LARK 飞书小程序
MP-QQ QQ小程序
MP-KUAISHOU 快手小程序
MP-JD 京东小程序
MP-360 360小程序
MP 微信小程序/支付宝小程序/百度小程序/字节跳动小程序/飞书小程序/QQ小程序/360小程序
QUICKAPP-WEBVIEW 快应用通用(包含联盟、华为)
QUICKAPP-WEBVIEW-UNION 快应用联盟
QUICKAPP-WEBVIEW-HUAWEI QUICKAPP-WEBVIEW-HUAWEI 快应用华为

支持的文件

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

# 打包上线

# 如何生成签名证书

# Android平台签名证书(.keystore)生成指南

Android平台打包发布apk应用,需要使用数字证书(.keystore文件)进行签名,用于表明开发者身份。

Android证书的生成是自助和免费的,不需要审批或付费。

可以使用JRE环境中的keytool命令生成。以下是windows平台生成证书的方法:

# 安装JRE环境(推荐使用JRE8环境,如已有可跳过)

可从Oracle官方下载jre安装包:https://www.oracle.com/technetwork/java/javase/downloads/index.html

下面以Windows平台,jre安装目录为“C:\Program Files\Java\jre1.8.0_201”为例,实际操作时请修改为自己安装目录

建议将JRE安装路径添加到系统环境变量,已配置可跳过此章节

打开命令行(cmd),输入以下命令:

d:  
set PATH=%PATH%;"C:\Program Files\Java\jre1.8.0_201\bin"
1
2
  • 第一行:切换工作目录到D:路径
  • 第二行:将jre命令添加到临时环境变量中

# 生成签名证书

使用keytool -genkey命令生成证书:

keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore
1
  • testalias是证书别名,可修改为自己想设置的字符,建议使用英文字母和数字
  • test.keystore是证书文件名称,可修改为自己想设置的文件名称,也可以指定完整文件路径
  • 36500是证书的有效期,表示100年有效期,单位天,建议时间设置长一点,避免证书过期 回车后会提示:

回车后会提示:

Enter keystore password:  //输入证书文件密码,输入完成回车  
Re-enter new password:   //再次输入证书文件密码,输入完成回车  
What is your first and last name?  
  [Unknown]:  //输入名字和姓氏,输入完成回车  
What is the name of your organizational unit?  
  [Unknown]:  //输入组织单位名称,输入完成回车  
What is the name of your organization?  
  [Unknown]:  //输入组织名称,输入完成回车  
What is the name of your City or Locality?  
  [Unknown]:  //输入城市或区域名称,输入完成回车  
What is the name of your State or Province?  
  [Unknown]:  //输入省/市/自治区名称,输入完成回车  
What is the two-letter country code for this unit?  
  [Unknown]:  //输入国家/地区代号(两个字母),中国为CN,输入完成回车  
Is CN=XX, OU=XX, O=XX, L=XX, ST=XX, C=XX correct?  
  [no]:  //确认上面输入的内容是否正确,输入y,回车  

Enter key password for <testalias>  
        (RETURN if same as keystore password):  //确认证书密码与证书文件密码一样(HBuilder|HBuilderX要求这两个密码一致),直接回车就可以
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

以上命令运行完成后就会生成证书,路径为“D:\test.keystore”

# iOS证书(.p12)和描述文件(.mobileprovision)申请

iOS有两种证书和描述文件:

证书类型 使用场景
开发(Development)证书和描述文件 用于开发测试,在 HBuilderX 中打包后可在真机环境通过Safari调试 (opens new window)
发布(Distribution)证书和描述文件 用于提交 AppStore,在 HBuilderX 中提交云打包后提交到 AppStore 审核发布

详见 https://ask.dcloud.net.cn/article/152

# 打包配置

# 基础配置

HBuilderX中打开项目的manifest.json文件,在“基础配置”中可以设置App的应用名称、版本号等信息:

# 图标配置

HBuilderX中打开项目的manifest.json文件,在“App图标配置”中可以设置App的桌面图标,推荐使用“自动生成图标”功能:

# 启动界面

App启动时,系统加载应用渲染首页需要一定的时间,为了避免用户等待,手机操作系统提供了特殊的启动界面设计,让用户先看到一个简单的界面,等应用加载完成后正式进入应用首页。 这个界面,即被称为启动界面,也成称为 splashlauch screen

Android平台自定义启动图

打开项目的manifest.json文件,在“App启动界面配置”中的“Android启动界面设置”项下勾选“自定义启动图”:

iOS平台自定义启动图

提示:2020年6月30日起,苹果AppStore审核要求应用在启动时,不能使用启动图片,必须改为使用Storyboard来制作启动界面,如果需要提交AppStore请使用通用启动界面 (opens new window)或自定义storyboard (opens new window)启动界面。

打开项目的manifest.json文件,在“App启动界面配置”中的“iOS启动界面设置”项下勾选“自定义启动图”:

# 功能模块

App端如用到以下相关模块,需要勾选相关模块的配置:

已定位功能为例,使用定位功能需在项目manifest.json的“App模块配置”中勾选“Geolocation(定位)”,并根据项目实际需求勾选使用的三方定位SDK:

# 开始打包

点击工具栏的发行 -> 原生App-云打包 选择要打包的平台安卓或ios(可同时勾选打包),输入证书别名和证书密码选择生成的相应平台证书,点击打包按钮开始打包。 经过几分钟的云打包后,在控制台点击地址下载相应的apk或ios包

# 上架应用市场

登录相应平台的开发者账号,上传apk提供相应资料和描述提交审核