uni-app
介绍 [官网]
什么是 uni-app[原文]
uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到 iOS、Android、Web(响应式)、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉/淘宝)、快应用等多个平台。
开发工具
- 推荐使用 HBuilderX;(也可以使用 vue-cli 创建项目后使用其他 IDE 开发)
- 相应平台的小程序开发工具;
[注] HBuilderX 下载有两个版本,如果不需要开发 APP 只下载标准版即可;
uni-app 由来
[查看原文]
uni,读 you ni,是统一的意思。
很多人以为小程序是微信先推出的,其实,DCloud 才是这个行业的开创者。
DCloud 于 2012 年开始研发小程序技术,优化 webview 的功能和性能,并加入 W3C 和 HTML5 中国产业联盟,推出了 HBuilder 开发工具,为后续产业化做准备。
2015 年,DCloud 正式商用了自己的小程序,产品名为“流应用”,它不是 B/S 模式的轻应用,而是能接近原生功能、性能的 App,并且即点即用,第一次使用时可以做到边下载边使用。
为将该技术发扬光大,DCloud 将技术标准捐献给工信部旗下的HTML5 中国产业联盟,并推进各家流量巨头接入该标准,开展小程序业务。
360 手机助手率先接入,在其 3.4 版本实现应用的秒开运行。
...
在 2015 年 9 月,DCloud 推进微信团队开展小程序业务,演示了流应用的秒开应用、扫码获取应用、分享链接获取应用等众多场景案例,以及分享了 webview 体验优化的经验。
微信团队经过分析,于 2016 年初决定上线小程序业务,但其没有接入联盟标准,而是订制了自己的标准。
...
如何学习
[查看原文]
建议第一步,看完uni-app 官网的首页介绍。
建议第二步,通过快速上手,亲身体验下 uni-app。
建议第三步,看完《uni-app 官方教程》,出品人:DCloud,课时:共 3 节。
如果你熟悉 h5,但不熟悉 vue 和小程序
- 看完这篇白话 uni-app
- DCloud 与 vue 合作,在vue.js 官网提供了免费视频教程,也可以直达教程地址:https://learning.dcloud.io
- 不需要专门去学习小程序的语法,uni-app 使用的是 vue 的语法,不是小程序自定义的语法。
如果你使用过 mpvue
几乎不用学习,uni-app 对 vue 语法的支持是 mpvue 的超集。这里有篇mpvue 转 uni-app 指南
如果你熟悉小程序,但不熟悉 vue
参考三方总结https://segmentfault.com/a/1190000015684864
...
关于各端的管理规则需要耐心学习
uni-app 并不难学,但我们注意到很多新人在适应各个平台的规则限制时比较急躁。
每个端,有每个端的管理规则,这不是 uni-app 在技术层面上可以抹平的:
- 比如 H5 端的浏览器有跨域限制;
- 比如微信小程序会强制要求 https 链接,并且所有要联网的服务器域名都要配到微信的白名单中;
- 比如 App 端,iOS 对隐私控制和虚拟支付控制非常严格;
- 比如 App 端,Android、国产 rom 各种兼容性差异,尤其是因为谷歌服务被墙,导致的 push、定位等开发混乱的坑;
- 如果你的 App 要使用三方 sdk,比如定位、地图、支付、推送...还要遵循他们的规则和限制;
遇事耐心,不急不躁,虽然这不是成功的唯一要素,但它是你技术路上长远走下去的基础。
框架简介
[查看原文]
开发规范、目录结构、资源路径、生命周期、路由、样式布局等...
开发规范
为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:
- 页面文件遵循 Vue 单文件组件 (SFC) 规范
- 组件标签靠近小程序规范,详见uni-app 组件规范
- 接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni,详见uni-app 接口规范
- 数据绑定及事件处理同 Vue.js 规范,同时补充了 App 及页面的生命周期
- 为兼容多端运行,建议使用 flex 布局进行开发
目录结构
一个 uni-app 工程,默认包含如下目录及文件:
┌─uniCloud 云空间目录,阿里云为uniCloud-aliyun,腾讯云为uniCloud-tcb(详见uniCloud)
│─components 符合vue组件规范的uni-app组件目录
│ └─comp-a.vue 可复用的a组件
├─hybrid App端存放本地html文件的目录,详见
├─platforms 存放各平台专用页面的目录,详见
├─pages 业务页面文件存放的目录
│ ├─index
│ │ └─index.vue index页面
│ └─list
│ └─list.vue list页面
├─static 存放应用引用的本地静态资源(如图片、视频等)的目录,注意:静态资源只能存放于此
├─uni_modules 存放[uni_module](/uni_modules)规范的插件。
├─wxcomponents 存放小程序组件的目录,详见
├─main.js Vue初始化入口文件
├─App.vue 应用配置,用来配置App全局样式以及监听 应用生命周期
├─manifest.json 配置应用名称、appid、logo、版本等打包信息,详见
└─pages.json 配置页面路由、导航条、选项卡等页面类信息,详见
资源路径说明
模板内引入静态资源
template 内引入静态资源,如 image、video 等标签的 src 属性时,可以使用相对路径或者绝对路径,形式如下
<!-- 绝对路径,/static指根目录下的static目录,在cli项目中/static指src目录下的static目录 -->
<image class="logo" src="/static/logo.png"></image>
<image class="logo" src="@/static/logo.png"></image>
<!-- 相对路径 -->
<image class="logo" src="../../static/logo.png"></image>
注意
- @开头的绝对路径以及相对路径会经过 base64 转换规则校验
- 引入的静态资源在非 h5 平台,均不转为 base64。
- H5 平台,小于 4kb 的资源会被转换成 base64,其余不转。
- 自 HBuilderX 2.6.6 起 template 内支持@开头路径引入静态资源,旧版本不支持此方式
- App 平台自 HBuilderX 2.6.9 起 template 节点中引用静态资源文件时(如:图片),调整查找策略为【基于当前文件的路径搜索】,与其他平台保持一致
- 支付宝小程序组件内 image 标签不可使用相对路径
js 文件引入
js 文件或 script 标签内(包括 renderjs 等)引入 js 文件时,可以使用相对路径和绝对路径,形式如下
// 绝对路径,@指向项目根目录,在cli项目中@指向src目录
import add from "@/common/add.js";
// 相对路径
import add from "../../common/add.js";
注意
- js 文件不支持使用/开头的方式引入
css 引入静态资源
css 文件或 style 标签内引入 css 文件时(scss、less 文件同理),可以使用相对路径或绝对路径(HBuilderX 2.6.6)
/* 绝对路径 */
@import url("/common/uni.css");
@import url("@/common/uni.css");
/* 相对路径 */
@import url("../../common/uni.css");
注意
- 自 HBuilderX 2.6.6 起支持绝对路径引入静态资源,旧版本不支持此方式
css 文件或 style 标签内引用的图片路径可以使用相对路径也可以使用绝对路径,需要注意的是,有些小程序端 css 文件不允许引用本地文件(请看注意事项)。
/* 绝对路径 */
background-image: url(/static/logo.png);
background-image: url(@/static/logo.png);
/* 相对路径 */
background-image: url(../../static/logo.png);
Tips
- 引入字体图标请参考,字体图标
- @开头的绝对路径以及相对路径会经过 base64 转换规则校验
- 不支持本地图片的平台,小于 40kb,一定会转 base64。(共四个平台
mp-weixin
,mp-qq
,mp-toutiao
,app v2
) - h5 平台,小于 4kb 会转 base64,超出 4kb 时不转。
- 其余平台不会转 base64
生命周期
应用生命周期
uni-app 支持 onLaunch、onShow、onHide 等应用生命周期函数,详情请参考应用生命周期
页面生命周期
uni-app 支持 onLoad、onShow、onReady 等生命周期函数,详情请参考页面生命周期
路由
uni-app 页面路由为框架统一管理,开发者需要在pages.json里配置每个路由页面的路径及页面样式。类似小程序在 app.json 中配置页面路由一样。所以 uni-app 的路由用法与 Vue Router 不同,如仍希望采用 Vue Router 方式管理路由,可在插件市场搜索 Vue-Router。
路由跳转
uni-app 有两种页面路由跳转方式:使用navigator组件跳转、调用API跳转。
页面样式与布局
uni-app 支持的通用 css 单位包括 px、rpx
- px 即屏幕像素
- rpx 即响应式 px,一种根据屏幕宽度自适应的动态单位。以 750 宽的屏幕为基准,750rpx 恰好为屏幕宽度。屏幕变宽,rpx 实际显示效果会等比放大,但在 App 端和 H5 端屏幕宽度达到 960px 时,默认将按照 375px 的屏幕宽度进行计算,具体配置参考:rpx 计算配置 。
vue 页面支持下面这些普通 H5 单位,但在 nvue 里不支持:
- rem 根字体大小可以通过 page-meta 配置
- vh viewpoint height,视窗高度,1vh 等于视窗高度的 1%
- vw viewpoint width,视窗宽度,1vw 等于视窗宽度的 1%
nvue 还不支持百分比单位。
App 端,在 pages.json 里的 titleNView 或页面里写的 plus api 中涉及的单位,只支持 px。注意此时不支持 rpx
nvue 中,uni-app 模式(nvue 不同编译模式介绍)可以使用 px 、rpx,表现与 vue 中一致。weex 模式目前遵循 weex 的单位,它的单位比较特殊:
- px:,以 750 宽的屏幕为基准动态计算的长度单位,与 vue 页面中的 rpx 理念相同。(一定要注意 weex 模式的 px,和 vue 里的 px 逻辑不一样。)
- wx:与设备屏幕宽度无关的长度单位,与 vue 页面中的 px 理念相同
下面对 rpx 详细说明:
设计师在提供设计图时,一般只提供一个分辨率的图。
严格按设计图标注的 px 做开发,在不同宽度的手机上界面很容易变形。
而且主要是宽度变形。高度一般因为有滚动条,不容易出问题。由此,引发了较强的动态宽度单位需求。
微信小程序设计了 rpx 解决这个问题。uni-app 在 App 端、H5 端都支持了 rpx,并且可以配置不同屏幕宽度的计算方式,具体参考:rpx 计算配置。
rpx 是相对于基准宽度的单位,可以根据屏幕宽度进行自适应。uni-app 规定屏幕基准宽度 750rpx。
开发者可以通过设计稿基准宽度计算页面元素 rpx 值,设计稿 1px 与框架样式 1rpx 转换公式如下:
设计稿 1px / 设计稿基准宽度 = 框架样式 1rpx / 750rpx
换言之,页面元素宽度在 uni-app 中的宽度计算公式:
750 * 元素在设计稿中的宽度 / 设计稿基准宽度
举例说明:
- 若设计稿宽度为 750px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在 uni-app 里面的宽度应该设为:750 * 100 / 750,结果为:100rpx。
- 若设计稿宽度为 640px,元素 A 在设计稿上的宽度为 100px,那么元素 A 在 uni-app 里面的宽度应该设为:750 * 100 / 640,结果为:117rpx。
- 若设计稿宽度为 375px,元素 B 在设计稿上的宽度为 200px,那么元素 B 在 uni-app 里面的宽度应该设为:750 * 200 / 375,结果为:400rpx。
Tips
- 注意 rpx 是和宽度相关的单位,屏幕越宽,该值实际像素越大。如不想根据屏幕宽度缩放,则应该使用 px 单位。
- 如果开发者在字体或高度中也使用了 rpx ,那么需注意这样的写法意味着随着屏幕变宽,字体会变大、高度会变大。如果你需要固定高度,则应该使用 px 。
- rpx 不支持动态横竖屏切换计算,使用 rpx 建议锁定屏幕方向
- 设计师可以用 iPhone6 作为视觉稿的标准。
- 如果设计稿不是 750px,HBuilderX 提供了自动换算的工具,详见:https://ask.dcloud.net.cn/article/35445。
- App 端,在 pages.json 里的 titleNView 或页面里写的 plus api 中涉及的单位,只支持 px,不支持 rpx。
- 早期 uni-app 提供了 upx ,目前已经推荐统一改为 rpx 了,详见
跨端兼容
组件
easycom 组件规范
传统 vue 组件,需要安装、引用、注册,三个步骤后才能使用组件。easycom 将其精简为一步。
只要组件安装在项目的 components 目录下或 uni_modules 目录下,并符合 components/组件名称/组件名称.vue 目录结构。就可以不用引用、注册,直接在页面中使用。
比如前述举例的uni-rate 组件,它导入到 uni-app 项目后,存放在了目录/components/uni-rate/uni-rate.vue
同时它的组件名称也叫 uni-rate,所以这样的组件,不用在 script 里注册和引用。 如下:
<template>
<view>
<uni-rate></uni-rate
><!-- 这里会显示一个五角星,并且点击后会自动亮星 -->
</view>
</template>
<script>
// 这里不用import引入,也不需要在components内注册uni-list组件。template里就可以直接用
export default {
data() {
return {};
},
};
</script>
不管 components 目录下安装了多少组件,easycom 打包后会自动剔除没有使用的组件,对组件库的使用尤为友好。
...
地图
注意事项
- 小程序和 app-vue 中,<map> 组件是由引擎创建的原生组件,它的层级是最高的,不能通过 z-index 控制层级。在<map>上绘制内容,可使用组件自带的 marker、controls 等属性,也可以使用<cover-view>组件。App 端还可以使用 plus.nativeObj.view 或 subNVue 绘制原生内容,参考。另外 App 端 nvue 文件不存在层级问题。从微信基础库 2.8.3 开始,支持 map 组件的同层渲染,不再有层级问题。
- App 端 nvue 文件的 map 和小程序拉齐度更高。vue 里的 map 则与 plus.map 功能一致,和小程序的地图略有差异。App 端使用 map 推荐使用 nvue。
- App 端使用到本地图像的话,打包前需要设置资源为释放模式,在 manifest 文件内 app-plus 新增 runmode 节点,设置值为 liberate。
- 在涉及层级问题的小程序中和 app-vue 中,请勿在 scroll-view、swiper、picker-view、movable-view 中使用 <map> 组件。
- 小程序和 app-vue 中,css 动画对 <map> 组件无效。
- map 组件使用的经纬度是国测局坐标,调用 uni.getLocation 接口需要指定 type 为 gcj02。
- <map> 组件在不同平台的底层引擎是不同的:H5、微信小程序为腾讯地图;App、支付宝小程序为高德地图;百度小程序、快应用为百度地图。app-vue 也可以使用百度地图,在 manifest 中配置,打包后生效,但 app-nvue 只支持高德地图。另外选择地图、查看地图位置的 API 也仅支持高德地图。App 端如无特殊必要,建议使用高德地图。
- map 组件默认的 api 是参考微信小程序的,如需要使用 plus.map,可以通过$getAppMap获取原生地图对象,详见。注意nvue的map组件不是plus.map对象,无法使用$getAppMap
- H5 端获取定位信息,需要部署在 https 服务上,本地预览(localhost)仍然可以使用 http 协议。
- 无 GPS 模块或 GPS 无信号的 PC 设备使用 Chrome 浏览器的时候,位置信息是连接谷歌服务器获取的,国内用户可能获取位置信息失败。
- App 端使用地图组件需要向高德或百度等三方服务商申请 SDK 资质,获取 AppKey,打包时需要在 manifest 文件中勾选相应模块,在 SDK 配置中填写 Appkey。注意申请包名和打包时的包名需匹配一致,证书信息匹配。在 manifest 可视化界面有详细申请指南。
- H5 端使用地图和定位相关需要在腾讯地图开放平台申请密钥,填写在 manifest.json 中。
- ios nvue Color 不支持 ARGB 十六进制,使用 rgba(r,g,b,a) 代替
API
uni-app 的 js API 由标准 ECMAScript 的 js API 和 uni 扩展 API 这两部分组成。
uni-app 中小程序相关 api 统一用 uni.xxx
调用, 如 wx.showLoading()
改为 uni.showLoading()
即可,便于跨平台开发,uni-app 会自动生成各平台的代码;
除了 uni-app 框架内置的跨端 API,各端自己的特色 API 也可通过条件编译自由使用。
Promise 封装
uni-app 对部分 API 进行了 Promise 封装,返回数据的第一个参数是错误对象,第二个参数是返回数据。
详细策略如下:
- 异步的方法,如果不传入 success、fail、complete 等 callback 参数,将以 Promise 返回数据。例如:uni.getImageInfo()
- 异步的方法且有返回对象,如果希望获取返回对象,必须至少传入一项 success、fail、complete 等 callback 参数。例如:uni.connectSocket()
- 同步的方法(即以 sync 结束),不封装 Promise。例如:uni.getSystemInfoSync()
- 以 create 开头的方法,不封装 Promise。例如:uni.createMapContext()
- 以 manager 结束的方法,不封装 Promise。例如:uni.getBackgroundAudioManager()
示例:
// 默认方式
uni.request({
url: "https://www.example.com/request",
success: (res) => {
console.log(res.data);
},
});
// Promise
uni
.request({
url: "https://www.example.com/request",
})
.then((data) => {
//data为一个数组,数组第一项为错误信息,第二项为返回数据
var [error, res] = data;
console.log(res.data);
});
// Await
async function request() {
var [error, res] = await uni.request({
url: "https://www.example.com/request",
});
console.log(res.data);
}
个人总结
基本
- 小程序基础
- 页面
- 组件
- 生命周期
- api
- 原生组件及其使用限制 重要
- vue.js
- vue 基础
- 生命周期、和标准 vue.js 的差异、小程序特有生命周期
- 状态管理 vuex 可选
- 小程序中的限制和差异 (如:不支持
v-show
)
- 屏幕适配(rpx)
- 设计稿最好以 750px 为基准;
- 设计稿上元素的尺寸直接使用
- 宽度
px
单位改成rpx
; - 高度如果需要和宽度保持比例不变也将
px
改为rpx
,如果需要高度固定则直接使用px
即可; - 字体如需与屏幕大小无关则使用
px
,如需等比调整大小则使用rpx
;
- 宽度
- Flex 布局
为支持跨平台,框架建议使用 Flex 布局,关于 Flex 布局可以参考外部文档 A Complete Guide to Flexbox、阮一峰的 flex 教程等。
- 第三方小程序库(可在插件市场找 https://ext.dcloud.net.cn/)
- 各平台差异
- 编译期可以确定的差异可以使用 条件编译 处理;
- 运行时才能确定的差异可以用 uni.getSystemInfoSync().platform 判断客户端环境,[参考这里];
- 了解各个平台的差异
- 如百度特有的
onInit
生命周期; - 百度的
app.json
中特有的routes
选项,可以自定义页面路由,但是 uni-app 还不支持,需要编译打包后手动添加到生成的百度小程序代码中;[参考这里] 很有用 - uni-app 目前使用百度动态库组件会报错找不到对应组件,这个好解决,是 uni-app 打包后的 app.json 中字段名错了,手动改正即可;
- 如百度特有的
- 关注各平台 api 最新变更,如微信 wx.getUserInfo 和 wx.getUserProfile;
额外推荐
- 粘性定位 position: sticky; [参考这里]
- 尽量用字体图标代替切图,参考 iconfont;
- uni-app 的 h5 路由和小程序体验一致