uniapp入门之旅

2,754 阅读18分钟

一、介绍

  1. 什么是uniapp?是干什么的?

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

  1. 为什么要使用
  • 移动端技术太多、跨端框架或是未来趋势
  • 一套代码多端发布、受开发者青睐
  • 完整的生态、受企业青睐(推送、广告、统计等功能、人员成本)
  1. 优势

image.png

  1. uni-app和Vue有什么关系
  • 使用vue技术开发
  • 发布到H5时,支持所有Vue的语法
  • 发布到App和小程序是,实现部分Vue语法
  1. uni-app和小程序有什么关系
  • 组件标签靠近小程序规范
  • 接口能力(JS API)靠近微信小程序规范
  • 完整的小程序生命周期
  1. 能力 | 能力 | Y/N | 说明 | | --- | --- | --- | | 跨端能力 | ✅ | 安卓、ios、微信小程序、其他小程序 | | 原生App唤起uni小程序能力 | ✅ | 需要集成uni小程序SDK并导入小程序wgt包 | | 原生App跳转小程序二级页面 | ✅ | 可以传递json、字符串等 | | uni小程序唤起原生App能力 | ✅ | 需要开发对应的Android/iOS插件,或通过插件市场下载,支持json、字符串等通用数据类型的传递 | | 第三方服务 | ✅ | 支付/推送/三方登录/分享/地图等 | | HBuilderX热编译 | ✅ | 支持手机、微信、浏览器实时预览 | | fragment/viewController嵌套小程序页面 | ❎ | 启动小程序相当于打开一个新的Activity,详见官网 | | uniapp页面加载原生fragment/viewController | ✅ | uni小程序在App端实际上是运行在一个WebActivity之上,可以拿到ActivityContext进而获取FragmentManager处理Fragment的展示隐藏,虽然这种方式可行,但是在uniapp上切换选项卡的时候要不断处理fragment的内部逻辑,相当于fragment生命周期的监控任务交给uniapp来执行而不是fragment本身 |

二,初始化

vue cli 终端命令行安装(需要掌握)

uniapp.dcloud.io/quickstart-…

HBuilder X 搭建uniapp(建议使用)

创建

uniapp.dcloud.io/quickstart-…

  • HBuilderX->文件->新建项目->选择模板

运行

发布

三、组件与api

1.组件的使用

uniapp.dcloud.io/component/v… uni-app为开发者提供了一系列基础组件,类似HTML里的基础标签元素。 但uni-app的组件与HTML不同,而是与小程序相同,更适合手机端使用。

  • 视图容器:view scroll-view等
  • 基础内容:text icon等
  • 表单组件:button form radio checkbox等
  • 媒体组件:video 等
  • 其他:地图,导航,画布,支付,扩展组件等

2.API调用

uniapp.dcloud.io/api/README

uni-app的js API由标准ECMAScript的js API 和 uni扩展 API 这两部分组成。

以上述代码为例,处理表单提交时,可以使用uni.showModal弹出一个提示框

formSubmit: function(e) {
	uni.showModal({
		content: '表单数据内容',
		showCancel: false
	});
}

如果想模拟一个网络请求,可以这样

uni.request({
    url: 'https://www.example.com/request', //仅为示例,并非真实接口地址。
    data: {
        text: 'uni.request'
    },
    header: {
        'custom-header': 'hello' //自定义请求头信息
    },
    success: (res) => {
        console.log(res.data);
        this.text = 'request success';
    }
});

3.自定义组件

封装可复用的组件,可以在其他的页面使用它。(和Vue的组件使用方法大致一样)

  • 首先编写一个组件
<template>
	<h3 @click='clickFun'>我是自定义组件:{{msg}}</h3>
</template>
<script>
	export default {
		name:'testComponent',
		props:{
			msg:{
				type:String,
				default:'default msg'
			}
		},
		methods:{
			clickFun:function(){
				this.msg = '改变后的组件属性',
				this.$emit('clickFun',this.msg);
			}
		}
	}
</script>
<style>
</style>
  • 在其他的组件中导入、声明、传入必要的参数并使用它
<template>
	<view>
		<!-- 3.自定义组件使用 msg是自定义组件的一个属性-->
		<testComponent style="margin-top: 50px;" msg="默认属性"  @clickFun="sonComponentClickCallback"></testComponent>
		<div>{{callback}}</div>
	</view>
</template>
<script>
    //1.导入
	import testComponent from '../components/testcomponent.vue'
	
	export default{
		components:{
		    //2.声明
			testComponent
		},
		data() {
			return {
				callback: ''
			}
		},
		methods:{
			sonComponentClickCallback:function(e){
				// this.callback = e;
				console.log(e);
			}
		}
	}
</script>
<style>
</style>

四、开发攻略

规范

uni-app 使用vue的语法结合小程序的标签和API。 为了实现多端兼容,综合考虑编译速度、运行性能等因素, uni-app 约定了如下开发规范:

  1. 页面文件遵循 Vue 单文件组件 (SFC) 规范
  2. 组件标签靠近小程序规范,详见uni-app 组件规范
  3. 接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni,详见uni-app接口规范
  4. 数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生命周期
  5. 为兼容多端运行,建议使用flex布局进行开发

像素单位

使用upx/rpx 而不是 px upx/rpx即响应式px,一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准,750rpx恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大。

生命周期

应用的生命周期

生命周期的概念:一个对象从创建、运行、销毁的整个过程被成为生命周期。 生命周期函数:在生命周期中每个阶段会伴随着每一个函数的触发,这些函数被称为生命周期函数 uni-app 支持如下应用生命周期函数:

函数名说明
onLaunchuni-app 初始化完成时触发(全局只触发一次)
onShowuni-app 启动,或从后台进入前台显示
onHideuni-app 从前台进入后台
onErroruni-app 报错时触发

页面的生命周期

uni-app 支持如下页面生命周期函数:

函数名说明
onLoad监听页面加载,其参数为上个页面传递的数据,参数类型为Object(用于页面传参),参考示例
onShow监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面
onReady监听页面初次渲染完成。
onHide监听页面隐藏
onUnload监听页面卸载

条件编译

uniapp.dcloud.io/platform

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

平台标识

平台参考文档
APP-PLUS5+AppHTML5+ 规范
H5H5
MP-WEIXIN微信小程序微信小程序
MP-ALIPAY支付宝小程序支付宝小程序
MP-BAIDU百度小程序百度小程序
MP-TOUTIAO头条小程序头条小程序
MP-QQQQ小程序
MP微信小程序/支付宝小程序/百度小程序/头条小程序/QQ小程序
MP-360360小程序
QUICKAPP-WEBVIEW快应用通用(包含联盟、华为)
QUICKAPP-WEBVIEW-UNION快应用联盟
QUICKAPP-WEBVIEW-HUAWEI快应用华为

支持的文件

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

组件的条件注释

<!-- #ifdef H5 -->
<view>
  h5页面会显示
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view>
  微信小程序会显示
</view>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view>
  app会显示
</view>
<!-- #endif -->

api的条件注释

onLoad () {
  //#ifdef MP-WEIXIN
  console.log('微信小程序')
  //#endif
  //#ifdef H5
  console.log('h5页面')
  //#endif
}

样式的条件注释

/* #ifdef H5 */
view{
  height: 100px;
  line-height: 100px;
  background: red;
}
/* #endif */
/* #ifdef MP-WEIXIN */
view{
  height: 100px;
  line-height: 100px;
  background: green;
}
/* #endif */

导航栏

导航栏注意的一个问题就是不同端的不同展示形式,所以需要处理兼容问题。 导航栏,可以用自定义的,可以用框架提供的,也有一些插件,都还是可以用的,就是注意显示的区别,如果有多端需求,一定要在不同端跑一下看看效果,不然到时候会很烦。 在支付宝小程序中,原生的导航栏是取消不了,所以不能用自定义的插件,就需要在page.json中配置原生的导航栏 头部导航是条件编译的:

资源路径说明

1)template内引入静态资源,如image、video等标签的src属性时,可以使用相对路径或者绝对路径:

<image class="logo" src="/static/logo.png"></image>
<image class="logo" src="@/static/logo.png"></image>
<image class="logo" src="../../static/logo.png"></image>

注意:

  1. @开头的绝对路径以及相对路径会经过base64转换规则校验
  2. H5平台小于4kb的资源会被转换成base64,其余平台不转。
  3. 支付宝小程序组件内 image 标签不可使用相对路径。

2)js文件或script标签内(包括renderjs等)引入js文件时,可以使用相对路径和绝对路径:

// 绝对路径,@指向项目根目录,在cli项目中@指向src目录
import add from '@/common/add.js'
// 相对路径
import add from '../../common/add.js'

注意:js文件不支持使用/开头的方式引入 3)css文件或style标签内引入css文件时(scss、less文件同理),可以使用相对路径或绝对路径:

/* 绝对路径 */
@import url('/common/uni.css');
@import url('@/common/uni.css');
/* 相对路径 */
@import url('../../common/uni.css');

4)css文件或style标签内引用的图片路径可以使用相对路径也可以使用绝对路径:

/* 绝对路径 */
background-image: url(/static/logo.png);
background-image: url(@/static/logo.png);
/* 相对路径 */
background-image: url(../../static/logo.png);

注意:

  1. 有些小程序端css文件不允许引用本地文件
  2. 引入字体图标请参考字体图标
  3. @开头的绝对路径以及相对路径会经过base64转换规则校验
  4. 不支持本地图片的平台,小于40kb,一定会转base64。
  5. h5平台,小于4kb会转base64,超出4kb时不转
  6. 其余平台不会转base64

插件市场和生态

ext.dcloud.net.cn/

总的来讲,Uniapp的插件市场还是不错的,大多数能用到的插件都可以找到,找不到的也可以从个别相似的插件中找到灵感,自己再魔改一下,论坛也还行,基本上自己遇到的问题都能找到答案,但是也有找不到的或者有人提出却无人回答的,官方qq群也还是比较热闹。 插件市场的插件安装一般是这种方式: image.png 点击按钮就可以安装到本地。这也分几种,我了解的就是组件类、编译类。像组件类,点击安装后会直接安装到当前打开的uniapp项目中,而且是指定的文件夹components中;像编译类,这种其实类似于webpack的loader,这个是放在hbx的安装包里。

五、云开发uniCloud

uniCloud 是 DCloud 联合阿里云、腾讯云,为开发者提供的基于 serverless 模式和 js 编程的云开发平台

uniCloud 的运行原理

  • 开发者在HBuilderX里为项目新建 uniCloud 云环境(可选择阿里云或腾讯云),在云函数目录下编写js代码,上传部署云函数到阿里云或腾讯云的 serverless 环境中。
  • 前端代码通过uniCloud.callFunction()方法调用云函数。
  • 云函数中可执行js运算、读写云化数据库(NoSQL)、读写存储和CDN、操作网络,给前端返回数据

开发过程,连接DCloud服务器;运行过程是手机端直连阿里云或腾讯云 serverless 环境,不通过DCloud服务器中转。 uniCloud 的底层环境,和微信小程序云开发、支付宝小程序云开发的基建环境相同。功能、性能、稳定性有足够的保障。腾讯云云开发(CloudBase)提供基础 serverless 能力,微信团队基于该能力封装了微信云开发,而DCloud团队基于该能力封装了 uniCloud。阿里云类似。

组成部分

  • 云函数:在云端运行的js代码。运行在定制过的node环境中,有良好的性能和强大的功能。serverless环境无需自行加购服务器处理增容,云函数按量付费,不管多大的并发都扛得住。
  • 数据库:基于 NoSQL 的 JSON 文档型数据库。这种数据库对于前端工程师更自然,不需要学习SQL,只需编写熟悉的js,即可玩转数据库。即便复杂的联表查询,也因uniCloud提供的JQL技术变的更加简单自然。
  • 存储和CDN:不管在前端还是云函数中,都可以操作存储和CDN。在uniCloud提供的安全机制下,可以实现应用前端直传CDN,避免服务器中转的耗时和带宽占用,且不会发生盗传。

创建项目

hBuilderX 新建项目

一定要选择 启用uniCloud才可以

  • 对于老的uni-app项目,也可以对项目点右键,菜单中选择“创建uniCloud云开发环境”

  • 新建uni-app项目的模板中,有一个Hello uniCloud项目模板,演示了各种云函数的使用。 uniCloud云开发环境创建成功后,项目根目录下会有一个带有云图标的特殊目录,名为“cloudfunctions”。(即便是cli创建的项目,云函数目录也在项目的根目录下,而不是src下) 非uni-app项目也可以通过使用云函数Url化来享受云函数的带来的便利。

创建和绑定服务空间

image.png

服务空间和手机端项目是多对多绑定关系。同账号下,一个项目可以关联到多个服务空间。一个服务空间也可以被多个项目访问。

  • 在云函数目录cloudfunctions右键菜单创建服务空间(HBuilderX 3.0以上版本请在uniCloud目录右键),会打开web控制台unicloud.dcloud.net.cn 进行创建
  • 创建好服务空间后,对目录cloudfunctions点右键(HBuilderX 3.0以上版本请在uniCloud目录右键),菜单中点击选择云服务空间,绑定你之前创建的服务空间。
  • 如果未进行实名认证,会跳转至实名认证页面进行实名认证,等待实名认证审核之后可以开通服务空间。若腾讯云实名认证提示身份证下已创建过多账户,则需要在腾讯云官网注销不用的账户。
  • 创建服务空间可能需要几十秒的时间,可以在web控制台查看是否创建完成。
  • 一个应用,可以在dev.dcloud.net.cn设置协作者(选择应用->设置项目成员),实现多人共同使用一个云服务空间。(需 HBuilderX 2.5.9+)需要注意的是目前协作者不可通过web控制台访问服务空间。

注:目前腾讯云仅提供一个服务空间。阿里云无限制

创建云函数

uniCloud项目创建并绑定服务空间后,开发者可以在cloudfunctions目录右键创建云函数(HBuilderX 3.0以上版本请在uniCloud/cloudfunctions目录右键)。

image.png

创建后会以云函数名称为名生成一个特殊目录,该目录下自动生成index.js,是该云函数的入口文件,不可改名。如果该云函数还需要引入其他js,可在index.js入口文件中引用。 注意

  • 不同项目使用同一个服务空间时,不可使用同名云函数,可以在uniCloud的web控制台手动删除重名云函数释放函数名。
  • 在HBuilderX创建云函数时,如果新云函数与服务器上已存在同名云函数,会用新函数覆盖。
  • 单个云函数大小限制为10M(包含node_modules)

编写云函数

云函数的语法,是在普通的Node.js基础上补充了uniCloud的专用API。可参考API开发文档编写,也可以直接新建项目时选择hello uniCloud模板体验。 HBuilderX为uniCloud开发提供了良好的语法提示和转到定义支持,对于代码中的API,选中并按下F1,也可以直接查看相应的文档。 如下为一个云函数示例

image.png

编写云函数后,在项目管理器里右键点击该云函数的目录,在弹出菜单中可选择“本地运行云函数”、“上传部署云函数”、“上传并运行云函数”。

  • 上传部署云函数:将云函数部署到uniCloud服务空间,不会运行。(快捷键Ctrl+u)
  • 上传并运行云函数:先上传云函数,并在云端立即执行该云函数。在部署后同时运行,并打印日志出来。有延时,调试时不如本地运行云函数快捷。
  • 本地运行云函数:在HBuilderX自带的node环境中运行选中的云函数。云函数连接的数据库和云存储,仍然在云端。(快捷键Ctrl+u)(从HBuilderX 2.8.1起支持)
  • 客户端连接本地云函数:开启一个uniCloud本地服务,运行前端项目时在HBuilderX控制台可切换访问云端云函数还是本地云函数。(从HBuilderX 3.0.0起支持)

到此一个uniCloud 云开发项目就创建好了。

六、现有项目如何迁移到uni-app体系

七、常见疑问

  1. 不同端有不同的需求、不同的特色,登陆支付也不一样,如何统一?

差异部分使用条件编译。uni-app提供了灵活强大的条件编译。可以完美处理复用部分和差异部分。真正一套工程源码。当业务升级时,不再需要多端维护。如果多端维护,经常会因为某些端的流量不大,就一直拖延无法让那些用户享受到最新服务。另外登陆支付在客户端部分,已经被uni-app统一成一样的api了。

  1. 多端是不是一种妥协,是否会造成性能下降?

多端且不影响性能,确实很难,但uni-app做到了。在h5端,它的性能、包体积与直接使用vue.js开发一致; 在小程序端,它的性能比大多数开发框架更好,uni-app底层自动处理的setdata差量同步机制,比开发者手动写setdata更好,就像使用vue.js更新界面比手动写js修改dom更高效一样; 在App,uni-app支持webview渲染和原生渲染双引擎,启用原生渲染时,css写法受限,但性能是很接近原生开发的效果的。当然也可以在已经做好的原生App中将部分页面改为uni-app实现; 此外,跨端处理放在编译期完成的,这样会减少对运行期的效率影响。

  1. 不做多端,是不是不需要uni-app?

不是。大量开发者用uni-app只做一个端。对于开发者而言,一个优秀工具在手,做什么都不愁。

八、总结

uni-app其实用起来是不难的,难就难在怎么兼容各端各平台的,为了兼容在代码加了不少#ifdef,还有一个难的点就是app打包了,由于前端不太熟悉安卓或者ios这些打包机制,只能按照uni-app的打包教程来配,但教程又写得很粗糙和不及时更新,像安卓开发工具androidStudio早就更新了,但是uniapp但教程还是没更新,只能靠自己摸索了

优缺点

结论:优点>缺点
虽然下面写了更多的缺点,但总体来看,优点远大于缺点

优点

  • 跨平台性,一次编写,到处运行(write once ,run everywhere)通过多平台打包发布到对应平台,节约大量开发成本
  • 对于前端开发人员比较友好,vue作为主流前端框架大多数人都掌握,只需要少量原生知识就能够开发跨平台的应用
  • 周边生态体系逐渐完善,很多大中小厂也在用,社区成长速度比较快

缺点

  • 正是由于跨平台特性,多端适配会占据相当的工作量,开发人员必须编写很多条件编译代码,这会破坏代码的整体结构(毕竟在业务代码中编写很多平台适配代码看起来太不优雅了),可读性也会受到一定影响,而且坑多是必然的
  • 对于Android和iOS开发人员来讲,转投uniapp学习成本很高(除了vue,还要学习html+js+css等知识),精通更是很难,这有点类似前两年移动端转投react native那样,会而不精,代码质量无法得到充分保证
  • 前端人员依然无法解决所有问题,至少在目前的应用场景中,很多需求仍然需要客户端人员配合开发(对于前端人员而言,学习安卓iOS的成本也相当可观)
  • 对于一些棘手的问题,参考的资料并不多,而且官方也很难第一时间回答你,甚至只能自己慢慢探索
  • 陈旧的api:以安卓为例,uniapp云打包apk反编译之后,发现入口程序PandoraEntry实际上是一个Activity而非API22(Android 5.1)后谷歌官方建议使用的v7包下的AppCompactActivity,这会影响ToolBar的使用

使用建议

  • 如果你熟悉React,不懂Vue.js,推荐Taro;
  • 如果你熟悉原生小程序,并且业务不涉及多端,则使用原生小程序(性能考虑);
  • 如果你熟悉Vue.js,则推荐 uni-app;
  • 如果你的业务涉及多端,更推荐 uni-app;
  • 如果你希望通过 serverless 方案快速上线业务,推荐 uni-app。

94940f8334124b5e9a7df042c88fafd6_tplv-k3u1fbpfcp-watermark.png