uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台。
体验效果可以扫描以下二维码:
官网地址:https://uniapp.dcloud.io/
uni-app与微信原生开发区别:
uni-app支持通过可视化界面、vue-cli命令行两种方式快速创建项目,本文是通过HBuilderX 可视化界面。HBuilderX内置相关环境,开箱即用,无需配置nodejs。HBuilderX是通用的前端开发工具,但为uni-app做了特别强化。
调试工具可以使用chrome浏览器或微信开发者工具等。如果只是为了开发微信小程序,推荐使用微信开发者工具进行调试和上传。
具体步骤如下:
1)安装HBuilderX和微信开发者工具
2)通过HBuilderX新建项目(点击工具栏里的文件 -> 新建 -> 项目)
3)配置开发工具的相关路径。(点击工具栏的运行 -> 运行到小程序模拟器 -> 运行设置,配置相应小程序开发者工具的路径)
4)运行uni-app(点击工具栏里的运行 -> 运行到小程序模拟器 -> 微信开发者工具)
5)第一次时打开微信开发者工具服务端口(打开微信开发者工具,点击工具栏里的设置->安全设置->服务端口:开启)
6)微信开发者工具会自动编译,并打开pages.json文件中pages里的第一个页面(通常定义为引导页或登录页)
为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:
┌─components uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─hybrid 存放本地网页的目录
├─platforms 存放各平台专用页面的目录
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用静态资源(如图片、视频等)目录,│ 注意:静态资源只能存放于此
├─wxcomponents 存放小程序组件的目录
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置全局样式以及监听生命周期
├─manifest.json 配置应用名称、appid、logo、版本等打包信息
└─pages.json 配置页面路由、导航条、选项卡等页面类信息
框架为开发者提供了一系列基础组件,类似HTML里的基础标签元素。
但uni-app的组件与HTML不同,而是与微信小程序相同,更适合手机端使用。
虽然不推荐使用HTML标签,但实际上如果开发者写了div等标签,在编译到非H5平台时也会被编译器转换为view标签,类似的还有span转text、a转navigator等,包括css里的元素选择器也会转。但为了管理方便、策略统一,新写代码时仍然建议使用view等组件。
开发者可以通过组合这些基础组件进行快速开发。 基于内置的基础组件,可以开发各种扩展组件,组件规范与vue组件相同。组件是视图层的基本组成单元。一个组件通常包括开始标签和结束标签,属性用来修饰这个组件,内容在两个标签之内。
共同属性类型
属性名 | 类型 | 描述 | 注解 |
---|---|---|---|
id | String | 组件的唯一标示 | 保持整个页面唯一 |
class | String | 组件的样式类 | 在对应的 css 中定义的样式类 |
style | String | 组件的内联样式 | 可以动态设置的内联样式 |
hidden | Boolean | 组件是否隐藏 | 所有组件默认是显示的 |
data-* | Any | 自定义属性 | 组件上触发的事件时,会发送给事件处理函数 |
@* | EventHandler | 组件的事件 | 详见各组件详细文档,事件绑定参考事件处理器 |
组件列表(共8类)
1)视图容器(View Container)
2)基础内容(Basic Content)
3)表单组件(Form)
4)导航(Navigation)
5)媒体组件(Media)
6)地图(Map)
7)画布(Canvas)
8)webview(Web-view)
API | 说明 | API | 说明 |
---|---|---|---|
uni.request | 发起网络请求 | uni.getRecorderManager | 录音管理 |
uni.uploadFile | 上传文件 | uni.downloadFile | 下载文件 |
uni.openDocument | 打开文件 | uni.saveFile | 保存文件 |
uni.chooseImage | 从相册选择图片,或者拍照 | uni.chooseVideo | 从相册选择视频,或者拍摄 |
uni.saveImageToPhotosAlbum | 保存图片到系统相册 | uni.saveVideoToPhotosAlbum | 保存视频到系统相册 |
uni.getStorage | 获取本地数据缓存(异步) | uni.getStorageSync | 获取本地数据缓存(同步) |
uni.setStorage | 设置本地数据缓存(异步) | uni.setStorageSync | 设置本地数据缓存 |
uni.clearStorage | 清理本地数据缓存(异步) | uni.clearStorageSync | 清理本地数据缓存 |
uni.getLocation | 获取当前位置 | uni.chooseLocation | 打开地图选择位置 |
uni.makePhoneCall | 拨打电话 | uni.scanCode | 扫码 |
uni.onUserCaptureScreen | 监听用户截屏事件 | uni.vibrate | 使手机发生振动 |
uni.showToast | 显示提示框 | uni.hideToast | 隐藏提示框 |
uni.showLoading | 显示加载提示框 | uni.hideLoading | 隐藏加载提示框 |
uni.showModal | 显示模态弹窗 | uni.showActionSheet | 显示菜单列表 |
uni.setNavigationBarTitle | 设置当前页面标题 | uni.navigateBack | 关闭当前页面,返回上一页面或多级页面 |
uni.navigateTo | 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面 | uni.redirectTo | 关闭当前页面,跳转到应用内的某个页面 |
uni.reLaunch | 关闭所有页面,打开到应用内的某个页面 | uni.switchTab | 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 |
uni-app 支持如下页面生命周期函数:
函数名 | 说明 | 平台差异说明 |
---|---|---|
onLoad | 监听页面加载,其参数为上个页面传递的数据,参数类型为Object(用于页面传参) | |
onShow | 监听页面显示。页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 | |
onReady | 监听页面初次渲染完成。注意如果渲染速度快,会在页面进入动画完成前触发 | |
onHide | 监听页面隐藏 | |
onUnload | 监听页面卸载 | |
onResize | 监听窗口尺寸变化 | App、微信小程序 |
onPullDownRefresh | 监听用户下拉动作,一般用于下拉刷新 | |
onReachBottom | 页面滚动到底部的事件(不是scroll-view滚到底),常用于上拉加载下一页数据。如使用scroll-view导致页面级没有滚动,则触底事件不会被触发 | |
onTabItemTap | 点击 tab 时触发,参数为Object | 微信小程序、百度小程序、H5、App(自定义) |
onShareAppMessage | 用户点击右上角分享 | 微信小程序、百度小程序、头条小程序、支付宝小程序 |
onPageScroll | 监听页面滚动,参数为Object | |
onNavigationBarButtonTap | 监听原生标题栏按钮点击事件,参数为Object | App、H5 |
onBackPress | 监听页面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack | App、H5 |
onNavigationBarSearchInputChanged | 监听原生标题栏搜索输入框输入内容变化事件 | App、H5 |
onNavigationBarSearchInputConfirmed | 监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。 | App、H5 |
onNavigationBarSearchInputClicked | 监听原生标题栏搜索输入框点击事件 | App、H5 |
页面文件放置在/pages文件夹下
新增的文件必须在/pages.json文件里注册,否则会找不到对应页面文件
导航栏页面还需要/pages.json文件的tabbar里注册
实际上路由功能是通过栈结构来实现的。普通情况下,新打开一个页面,那么新页面入栈,后退,则栈顶元素出栈。因为栈容量有限,所以不能无限制跳转新页面。
uni.navigateTo
介绍:保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面。
使用场景:列表页->详情页
实质:页面栈入栈
uni.navigateBack
介绍:关闭当前页面,返回上一页面或多级页面
使用场景:保存成功后,回退到上一页面
实质:页面栈出栈
uni.redirectTo
介绍:关闭当前页面,跳转到应用内的某个页面
使用场景:主页面->扫码页->结果页(希望后退时返回到主页面而不是扫码页)主页面->扫码页使用uni.navigateTo,扫码页->结果页用uni.redirectTo
实质:页面栈先出栈,再入栈
uni.reLaunch
介绍:关闭所有页面,打开到应用内的某个页面
使用场景:引导页1、2、3->登录页
实质:页面栈清空,再入栈
uni.switchTab
介绍:跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面
使用场景:设备管理->设置
uni-app 组件支持的生命周期,与vue标准组件的生命周期相同。这里没有页面级的onLoad等生命周期:
函数名 | 说明 | 平台差异说明 |
---|---|---|
beforeCreate | 在实例初始化之后被调用。 | |
created | 在实例创建完成后被立即调用。 | |
beforeMount | 在挂载开始之前被调用。 | |
mounted | 挂载到实例上去之后调用。注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTick | |
beforeUpdate | 数据更新时调用,发生在虚拟 DOM 打补丁之前。 | 仅H5平台支持 |
updated | 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。 | 仅H5平台支持 |
beforeDestroy | 实例销毁之前调用。在这一步,实例仍然完全可用。 | |
destroyed | Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 |
组件放在/components文件夹中
使用时,先import组件,然后再components里声明,再使用
正向传递(父组件->子组件):props和ref
prop 着重于数据的传递,它并不能调用子组件里的属性和方法。像创建文章组件时,自定义标题和内容这样的使用场景,最适合使用props。
ref 着重于索引,主要用来调用子组件里的属性和方法,其实并不擅长数据传递。而且ref用在dom元素的时候,能起到选择器的作用,这个功能比作为索引更常有用到。
例如:
父组件中:range=“range”//将range值传给子组件
子组件中:子组件的props选项能够接收来自父组件数据
ref 用于调用子组件的函数(refs是所有ref的集合)
逆向传递(子组件->父组件):
子组件中:使用$emit( eventName, […args] )传递数据
父组件中:@eventName 接收传递的值(传递的值在e中)
1)在微信公众平台(https://mp.weixin.qq.com/),注册小程序(目前申请企业微信小程序需要15位营业执照注册号或18位的统一社会信用代码。为验证真实性需要用对公账户小额打款,验证成功后打款将原路退回。)
2)成功后登录微信公众平台,在设置中设置小程序基本信息,并记录小程序ID
3)在HBuilderX中配置相关信息
4)在微信开发者工具中上传小程序,小程序分为体验版本、审核版本、线上版本。上传会覆盖体验版本,经过审核并通过之后,可以发布为正式版本。审核前需要正确填写小程序相关信息,提交的小程序须是一个完成品。若小程序中存在帐号体系,需提供可以使用所有功能的测试号,包含帐号和密码。
6.常见问题与解决方案
1)页面跳转url有长度限制
可使用窗体通信、全局变量,或encodeURIComponent等多种方式解决
传值页面用encodeURIComponent,接收值页面用decodeURIComponent
2)页面跳转次数过多会无法正常跳转
原因见本文4.1.4页面跳转,解决方法是避免过深的层级或使用uni.redirectTo,uni.reLaunch而不是uni.navigateTo(但是会导致无法按原路径后退)
3)条件编译
每个平台有自己的一些特性,因此会存在一些无法跨平台的情况。
条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。例如以 //ifdef 或 //ifndef 加 %PLATFORM% 开头,以 //endif 结尾。
4)picker(滚动选择器)value 的值表示选择了数组中的第几个(下标)
如果需要得到选中项对应的id,可以根据下标取数组对应对象,再取id
5)textarea等组件层级过高会导致显示在弹出页面之上(穿模问题)
部分组件如map、video、textarea、canvas通过原生控件实现,原生组件层级高于前端组件,为了能正常覆盖原生组件,可以用cover-view。也可以在textarea中加如v-if,弹出新弹窗时隐藏textarea,新弹窗关闭时显示textarea。
6)在详情页删除后,回退到列表页,已删除项仍显示
获取列表数据的函数getData()放在onShow()中,而不是onLoad()中。
7)打开调试工具可以发送网络请求,关闭之后报错
uni.request中的url必须使用域名,必须支持https访问,而且需要在微信公众平台->开发->开发设置中设置服务器域名。