一、什么是 uni-app?
uni-app 这个框架是基于Vue.js开发的,通过uni-app可以开发出跨平台的产品,所以如果对vue有一定的了解,那么这套框架可以很快速的掌握,当然,如果你对微信小程序也了解的话,也能够迅速掌握的,因为Uni-App封装并且兼容了微信小程序的组件和api。开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。
二、为什么要选择uni-app?
对比其他移动端跨平台框架(如Cordova/ReactNative/NativeJS),UniApp在跨端抹平度、扩展灵活性、性能体验、周边生态、开发成本等几个方面上拥有明显的优势。
(1)跨端数量多:一套代码,编译后可发布到iOS、Android、H5、小程序等多个平台,且跨端抹平度高,应用的显示效果接近一致,真正能落实到生产力。这一点是uniapp的最大优势,完胜其他跨平台框架。
(2)性能体验优秀:uniapp是体验更好的Hybrid框架,加载新页面速度更快。且App端支持weex原生渲染,可实现更流畅的动画效果。相比较而言,依赖于WebView的Cordova框架性能方面就有所欠缺了。
(3)生态开放丰富:uniapp的插件市场,集成了近千余第三方插件,各种轮子拿来即用;同时,由于uniapp的接口API采用了小程序规范,微信生态的各种SDK可直接用于跨平台App。在这个方面作对比,React Native框架的社区活跃度和资料文档都较为有限。
(4)开发成本低:以前由N个平台开发人员(IOS/安卓/H5)完成的开发任务,现在采用前端通用技术栈实现,研发、维护、测试各环节的成本都大幅下降。
同时,HBuilderX工具搭配uniapp可以免终端调试,可视化创建项目、可视化安装组件和扩展编译器,研发人员的开发体验也变得更好,从而能够更高效地编写代码。
三、uniapp发展史
uni是统一的意思。
很多人以为小程序是微信先推出的,其实,DCloud才是这个行业的开创者。
DCloud于2012年开始研发小程序技术,优化webview的功能和性能,并加入W3C和HTML5中国产业联盟,推出了HBuilder开发工具,为后续产业化做准备。
2015年,DCloud正式商用了自己的小程序,产品名为“流应用”,它不是B/S模式的轻应用,而是能接近原生功能、性能的动态App,并且即点即用。
为将该技术发扬光大,DCloud将技术标准捐献给工信部旗下的HTML5中国产业联盟,并推进各家流量巨头接入该标准,开展小程序业务。
随后DCloud推动大众点评、携程、京东、有道词典、唯品会等众多开发者为流应用平台提供应用。
在2015年9月,DCloud推进微信团队开展小程序业务,演示了流应用的秒开应用、扫码获取应用、分享链接获取应用等众多场景案例,以及分享了webview体验优化的经验。
微信团队经过分析,于2016年初决定上线小程序业务,但其没有接入联盟标准,而是订制了自己的标准。
DCloud持续在业内普及小程序理念,推进各大流量巨头,包括手机厂商,陆续上线类似小程序/快应用等业务。
部分公司接入了联盟标准,但更多公司因利益纷争严重,标准难以统一。
技术是纯粹的,不应该因为商业利益而分裂。开发者面对如此多的私有标准不是一件正确的事情。
造成混乱的局面非DCloud所愿。于是就决定开发一个免费开源的框架。
既然各巨头无法在标准上达成一致,官方希望通过这个框架为开发者抹平各平台差异。这就是uni-app的由来。
四、功能框架
下面是uni-app功能框架图,图中直观的表现了uniapp出色的跨平台能力和各平台特色。不多说,直接上图:
从上面uni-app功能框架图可看出,uni-app在跨平台的过程中,不牺牲平台特色,可优雅的调用平台专有能力。用官方的话说就是:海纳百川、各取所长。
概念导入:
- (1)什么是H5+?
HTML5plus Runtime,简称5+ Runtime,是运行于手机端的强化web引擎,除了支持标准HTML5外,还支持更多扩展的js api,使得js的能力不输于原生。5+ Runtime内置于HBuilder,在真机运行、打包时自动挂载。
业内之前有phonegap/Cordova方案,但是他们自带js api太少了,扩展api需要用原生语言开发,更致命的是这类方案的性能不足。
封装成跨平台的HTML5plus规范,并将规范公开于www.HTML5plus.org,不做厂商私有API。包括二维码、摇一摇、语音输入、地图、支付、分享、文件系统、通讯录等常用API,可以方便简单的编写,并且可跨平台。
注意:uni-app不需要 plus ready
在html中使用plus的api,需要等待plus ready。 而uni-app不需要等,可以直接使用。而且如果你调用plus ready,反而不会触发。
小程序及 H5 等平台是没有 HTML5+ 扩展规范的,因此在 uni-app 调用 HTML5+ 的扩展规范时,需要注意使用条件编译。否则运行到h5、小程序等平台会出现 plus is not defined错误。
- (2)什么是条件编译?
条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。
写法:以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。
- · #ifdef:if defined 仅在某平台存在
- · #ifndef:if not defined 除了某平台均存在
- · %PLATFORM%:平台名称
%PLATFORM% 可取值如下:
注意:
- · 条件编译是利用注释实现的,在不同语法里注释写法不一样,js使用 // 注释、css 使用 /* 注释 */、vue/nvue 模板里使用 <!-- 注释 -->;
- · 条件编译APP-PLUS包含APP-NVUE和APP-VUE,APP-PLUS-NVUE和APP-NVUE没什么区别,为了简写后面出了APP-NVUE ;
API 的条件编译
// #ifdef %PLATFORM%
平台特有的API实现
// #endif
- (3)什么是nvue?
uni-app App端内置了一个基于 weex 改进的原生渲染引擎,提供了原生渲染能力。
在App端,如果使用vue页面,则使用webview渲染;如果使用nvue页面(native vue的缩写),则使用原生渲染。一个App中可以同时使用两种页面,比如首页使用nvue,二级页使用vue页面。
注意:虽然nvue也可以多端编译,输出H5和小程序,但nvue的css写法受限,所以如果你不开发App,那么不需要使用nvue。
- (4)Uniapp编译模式是怎样的?
最初uni-app仅支持模板编译模式和自定义组件模式,在后来的升级中逐渐用V3编译模式取代,v3是针对App的改进,尤其是vue页面的改进。与其他平台无关。目前V3已成为默认的编译模式。此外uni-app还支持对nvue编译模式的选择,分为weex编译模式和uni-app编译模式,这里不做详细解读,有兴趣的同学可以自行学习。
五. 如何使用uni-app?
(1) 下载开发工具:HBuilderX
打开dcloud官网 http://www.dcloud.io/hbuilderx.html 推荐直接下载App开发版本,可以免去后续配置及安装插件等的烦恼
(2) 安装并打开HBuilderX
之后,在点击工具栏里的文件 -> 新建 -> 项目
- (3) 选择uni-app,输入工程名,如:uni-test,点击创建,成功创建 UniApp应用。点击模板里的 Hello uni-app 即可体验官方示例。
- (4) 随着官方的不断迭代升级,现已支持创建多套模板,可以便捷的搭建项目框架,已内置大量常用组件,免去了搭建项目的大部分前期工作,这点非常方便。如下是 uni ui项目模板的常见例子,供大家参考。
(4)创建DCloud appid(以后简称 appid)。appid是 DCloud 应用的唯一标识,在 DCloud 提供的所有服务中,都会以 appid 来标记一个应用。注意这和各家小程序的appid以及Apple的appid(其实就是iOS的包名)是两套体系。
- l 登录开发者中心,申请创建 uniapp、5+app 等类型应用的 appid;
- l 在 HBuilderX登录的情况下, 创建项目时,HBuilderX 也会自动联网生成 appid, 并将该 appid 保存在 manifest 文件中的 appid 字段;
(5)工程目录结构
(6)进入项目,点击工具栏的运行 -> 运行到浏览器/真机下运行/模拟器运行,也可以选择小程序在微信开发者工具里运行,如下是项目运行的示例。
浏览器运行:进入hello-uniapp项目,点击工具栏的运行 -> 运行到浏览器 -> 选择浏览器,即可在浏览器里面体验uni-app 的 H5 版。
真机运行:连接手机,开启USB调试,进入hello-uniapp项目,点击工具栏的运行 -> 真机运行 -> 选择运行的设备,即可在该设备里面体验uni-app。
如手机无法识别,请点击菜单运行-运行到手机或模拟器-真机运行常见故障排查指南。 注意开发App也需要安装微信开发者工具。
(7)发布uni-app
Unapp有两种发布形式:打包为原生App(云端)和打包为原生App(离线)。由于离线打包需要一定原生基础,且sdk不能随官方升级,实时更新,一般采用app-云端打包的形式。
在HBuilderX工具栏,点击发行,选择原生app-云端打包,如下图:
出现如下界面,点击打包即可。
打包为原生App(离线)
uni-app 支持离线打包,在 HBuilderX 发行菜单里生成离线打包资源,然后参考离线打包文档操作,可以从HBuilderX的发行菜单里找到文档链接,也可以直接访问:https://nativesupport.dcloud.net.cn/AppDocs/README。
在HBuilderX工具栏,点击发行,选择本地打包,如下图,点击即可生成离线打包资源。
发布为H5
- 1. 在 manifest.json 的可视化界面,进行如下配置(发行在网站根目录可不配置应用基本路径),此时发行网站路径是 www.xxx.com/h5,如:https://hellouniapp.dcloud.net.cn。
- 2. 在HBuilderX工具栏,点击发行,选择网站-H5手机版,如下图,点击即可生成 H5 的相关资源文件,保存于 unpackage 目录。
注意
- l history 模式发行需要后台配置支持。
- l 打包部署后,在服务器上开启 gzip 可以进一步压缩文件。
发布为小程序
发布为微信小程序:
- 1. 申请微信小程序AppID,参考:微信教程。
- 2. 在HBuilderX中顶部菜单依次点击 "发行" => "小程序-微信",输入小程序名称和appid点击发行即可在 unpackage/dist/build/mp-weixin 生成微信小程序项目代码。
- 3. 在微信小程序开发者工具中,导入生成的微信小程序项目,测试项目代码运行正常后,点击“上传”按钮,之后按照 “提交审核” => “发布” 小程序标准流程,逐步操作即可,详细查看:微信官方教程。
六、开发规范
(1)页面文件 遵循Vue单页面组件规范,Vue中的结构依然采用三大顶级代码块:vue-loader规范
(2)组件标签 VUE通用模板写法,编译后以IOS或Android原生UI控件渲染
(所以不能使用标准的HTML标签,JS对DOM操作也得尽量避免),示例:
- (3)接口能力: 基本遵循微信小程序规范,对于大部分接口地址前缀由wx修改为uni即可实现,也包括了uni特有的一些api,具体参考:https://uniapp.dcloud.io/api/README
随着severless的发展,uniapp还提供了基于unicloud的云函数、云数据库、云存储和CDN方案,uniCloud 是 DCloud 联合阿里云、腾讯云,为开发者提供的基于 serverless 模式和 js 编程的云开发平台。
此外,uniapp还提供了了很多
- (4)样式控制:
uni-app 支持通用 css 单位包括 px;另外,针对屏幕宽度自适应的普遍需求,推出了响应式px的概念,最初,uniapp以upx为尺寸单位,在框架的升级过程中,借鉴了微信小程序rpx的设计理念,转为rpx。
rpx 是相对于基准宽度的单位,可以根据屏幕宽度进行自适应。uni-app 规定屏幕基准宽度 750rpx。
开发者可以通过设计稿基准宽度计算页面元素 rpx 值,设计稿 1px 与框架样式 1rpx 转换公式如下:
设计稿 1px / 设计稿基准宽度 = 框架样式 1rpx / 750rpx
换言之,页面元素宽度在 uni-app 中的宽度计算公式:
750 * 元素在设计稿中的宽度 / 设计稿基准宽度
(5)uniapp开发与传统前端开发的异同点:
传统的h5只有1端,即浏览器。而uni-app可跨多端,虽仍属前端,与传统h5有不同。
网络模型的变化
以前网页大多是b/s,服务端代码混合在页面里;
现在是c/s,前后端分离,通过js api(类似ajax的uni.request)获取json数据,把数据绑定在界面上渲染。
文件类型变化
以前是.html文件,开发也是html,运行也是html。
现在是.vue文件,开发是vue,经过编译后,运行时已经变成了js文件。
现代前端开发,很少直接使用HTML,基本都是开发、编译、运行。所以uni-app有编译器、运行时的概念。
文件内代码架构的变化
以前一个html大节点,里面有script和style节点;
现在template是一级节点,用于写tag组件,script和style是并列的一级节点,也就是有3个一级节点。
外部文件引用方式变化
以前通过script src、link href引入外部的js和css;
现在是es6的写法,import引入外部的js模块(注意不是文件)或css
示例
var dateUtils = require('../../../common/util.js').dateUtils; //直接使用js模块的属性。在hello uni-app有示例
import * as echarts from '/components/echarts/echarts.simple.min.js'; //将js导入并重命名为echarts,然后使用echarts.来继续执行方法。在hello uni-app有示例
css外部文件导入
<style>
@import "./common/uni.css";
.uni-hello-text{
color:#7A7E83;
}
</style>
全局样式,在根目录下的app.vue里写入,每个页面都会加载app.vue里的样式。
另外,vue支持组件导入,可以更方便的封装一个包括界面、js、样式的库。
如下是导入一个角标的组件库,在页面上显示一个abc并且右上角有个数字角标1,
<template>
<view>
<uni-badge text="abc" :inverted="true"></uni-badge><!--3.使用组件-->
</view>
</template>
<script>
import uniBadge from "../../../components/uni-badge.vue";//1.导入组件(这步属于传统vue规范,但在uni-app的easycom下可以省略这步)
export default {
data() {
return {
}
},
components: {
uniBadge //2.注册组件(这步属于传统vue规范,但在uni-app的easycom下可以省略这步)
}
}
</script>
如需要全局导入vue组件,即每个页面都可以直接使用而不用引用和注册的话,在项目根目录下的main.js里处理。
组件/标签的变化
以前是html标签,比如<div>,现在是小程序组件,比如<view>。
那么标签和组件有什么区别,不都是用尖括号包围起来一段英文吗?
其实标签是老的概念,标签属于浏览器内置的东西。但组件,是可以自由扩展的。
类似你可以把一段js封装成函数或模块,你也可以把一个ui控件封装成一个组件。
uni-app参考小程序规范,提供了一批内置组件。
下为html标签和uni-app内置组件的映射表:
- § div 改成 view
- § span、font 改成 text
- § a 改成 navigator
- § img 改成 image
- § input 仅仅是输入框。 原html规范中input不仅是输入框,还有radio、checkbox、时间、日期、文件选择功能。在uni-app和小程序规范中,input仅仅是输入框。其他功能uni-app有单独的组件或API:radio组件、checkbox组件、时间选择、日期选择、图片选择、视频选择、多媒体文件选择(含图片视频)、通用文件选择。
- § 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组件。详见层级介绍
除了内置组件,还有很多开源的扩展组件,把常用操作都进行封装,DCloud建立了插件市场收录这些扩展组件,详见插件市场
js的变化
js的变化,分为运行环境变化、数据绑定模式变化、api变化3部分。
运行环境从浏览器变成v8引擎
标准js语法和api都支持,比如if、for、settimeout、indexOf等。
但浏览器专用的window、document、navigator、location对象,包括cookie等存储,只有在浏览器中才有,app和小程序都不支持。
js是ECMAScript组织管理的,浏览器中的js是w3c组织基于js规范补充了window、document、navigator、location等专用对象。
在uni-app的各个端中,除了h5端,其他端的js都运行在一个独立的v8引擎下,不是在浏览器中,所以浏览器的对象无法使用。如果你做过小程序开发,对此应当很了解。
这意味着依赖document的很多HTML的库,比如jqurey无法使用。
当然app和小程序支持web-view组件,里面可以加载标准HTML,这种页面仍然支持浏览器专用对象window、document、navigator、location。
uni-app使用vue的数据绑定方式解决js和dom界面交互的问题。
在普通vue页面里的生命周期叫页面生命周期。在项目根目录的app.vue文件中的生命周期叫应用生命周期。
除了onload,还有onready等很多生命周期,具体见uni-app的生命周期
js api的变化
- § 因为uni-app的api是参考小程序的,所以和浏览器的js api有很多不同,如
- § alert,confirm 改成 uni.showmodel
- § ajax 改成 uni.request
- § cookie、session 没有了,local.storage 改成 uni.storage
- § uni-app的js api还有很多,但基本就是小程序的api,把wx.xxx改为uni.xxx即可。
css的变化
- § 标准的css基本都是支持的。
- § 选择器有2个变化:*选择器不支持;元素选择器里没有body,改为了page。微信小程序即是如此。
page{
}
注意css里背景图和字体文件,尽量不要大于40k,因为会影响性能。在小程序端,如果要大于40k,需放到服务器侧远程引用或base64后引入,不能放到本地作为独立文件引用。
工程结构和页面管理
uni-app的工程结构有单独的要求,上面例子中有讲到过:
每个可显示的页面,都必须在 pages.json 中注册。如果你开发过小程序,那么pages.json类似app.json。如果你熟悉vue,这里没有vue的路由,都是在pages.json里管理。
原来工程的首页一般是index.html或default.html,是在web server里配的。而uni-app的首页,是在pages.json里配的,page节点下第一个页面就是首页。一般在/pages/xx的目录下。
app和小程序中,为了提升体验,页面提供了原生的导航栏和底部tabbar,注意这些配置是在pages.json中做,而不是在vue页面里创建。如果你熟悉小程序开发的话,对比变化如下:
- § 原来app.json被一拆为二。页面管理,被挪入了uni-app的pages.json;非页面管理,挪入了manifest.json
- § 原来的app.js和app.wxss被合并到了app.vue中
七、uni-app基本原理
技术的发展日新月异,各项新技术、新概念层出不穷。随着“微前端”理念发展,特别是微信小程序技术的“后发先至”,加速了uni-app的推出进程。结合实际项目中的使用分析来看,uniapp的实现更应该是文件预处理、编译技术和架构理念的更新,随着微信小程序的广为人知,及各家小程序的相互“借鉴”,uniapp迎合了这一趋势,为更好的发挥“流应用”框架的跨平台的能力,因此采用了近似小程序的项目架构。
实际上,不管是就跨平台、适配、还是条件编译等等,类比webpack预编译的实现方式和vue框架在vue-loader上的处理方式,我们不难理解uniapp在各平台先编译后运行的基本原理,其最终目的都是通过后期的编译,来实现各端在规范和格式上的统一。
- 八、扩展能力和开发生态
uniapp支持混和开发和uni小程序开发。uni-app 积极拥抱社区,创建了开放、兼容的生态系统。
总结
uni-app从诞生至今,经过了uni官方和广大开发者长时间的打磨过程,“野蛮生长”的洪荒时代业已成为过去,如今,使用uni-app 在UI表现力、性能体验、生态成熟度几个维度都能经得起推敲。发展到现在,即便框架本身有着低成本的特性,uni-app仍然是一套相对完整的体系,还有很多方面很难一言蔽之。
综合来讲,uni-app在开发者数量、案例、灵活性、生态、开发成本等关键指标上有一定优势,能够满足大部分的基础需求,就学习成本而言,较容易上手,也为前端开发者提供了更多的可能,值得推荐。当然,任何框架都首先要服务于实际业务需求,技术的选型也需根据研发团队成员的技术方向和具体情况而定,对于项目建设而言技术框架没有最好的只有最适合的。
以上仅是我自己的一孔之见,这里抛砖引玉,欢迎大家积极交流意见和建议,共同学习和进步,谢谢大家!