开发规范:
为了实现多端兼容,综合考虑编译速度、运行性能等等因素,uni-app 约定了如下开发规范:
- 页面文件遵循Vue 单文件组件 (SFC) 规范
- 组件标签靠近小程序规范,详见uni-app 组件规范
- 接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni ,详见uni-app接口规范
- 数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生成周期
- 为兼容多端运行,建议使用 flex布局 进行开发
目录结构:
一个 uni-app工程,默认包含如下目录和文件:
注意:
- static 目录下的 js 文件不会被编译,如果里面有 es6 的代码,不经过转换直接运行,在手机设备上会报错
- css、less/scss 等资源文件同样不要放在 static 目录下,建议这些公用的资源放在 common 目录下
- HBuilderX 1.9.0+ 支持在根目录创建 ext.json、sitemap.json 文件
有效目录 | 说明 |
app-plus | App |
h5 | H5 |
mp-weixin | 微信小程序 |
mp-alipay | 支付宝小程序 |
mp-baidu | 百度小程序 |
资源路径说明:
模板内引入静态资源:
在 template 标签中 通过 image、video等标签的 src 属性引入静态资源时,可以使用相对路径或绝对路径,如下代码:
注意:
- @开头的绝对路径以及相对路径会经过 base64 转换规则校验
- 引入的静态资源在非h5平台,均不转为 base64
- H5 平台,小于4kb的资源会被转换为 base 64,其余不转
- 自 HBuilderx 2.6.6-alpha 起 template 内支持 @ 开头路径引入静态资源,旧版本不支持此方法
- App平台自HBuilderX 2.6.9-alpha起template节点中引用静态资源文件时(如:图片),调整查找策略为【基于当前文件的路径搜索】,与其他平台保持一致
- 支付宝小程序组件内 image 标签不可使用相对路径
js文件引入:
js 文件或 script 标签内(包括renderjs等)引入 js 文件时,可以使用相对路径和绝对路径,形式如下:
注意:
js 文件不支持使用 / 开头的方式引入。
css引入静态资源:
css 文件或 style标签 内引入 css 文件(scss、less文件同理)时,可以使用相对路径或绝对路径,如下代码:
注意:
自 HBuilderX 2.6.6-alpha 起支持绝对路径引入静态资源,旧版本不支持此种方式。
css 文件或 style 标签 内引用的图片路径可以使用相对路径,也可以使用绝对路径。需要注意的是,有些小程序端 css文件不允许引用本地文件(请看注意事项)
注意:
1、引入字体图标请参考 字体图标
2、 @ 开头的绝对路径以及相对路径会经过base64 转换规则校验
3、不支持本地图片的平台,小于40kb,一定会转 base64 (共四个平台mp-weixin, mp-qq, mp-toutiao, app v2)
4、h5平台,小于4kb会转base64,超出4kb时不转
5、其余平台不会转 base64
在 .vue 文件中进入外部 css 文件,如下示例代码:
生命周期:
应用生命周期:
uni-app 支持如下应用生命周期函数:
函数名 | 说明 |
onLaunch | 当uni-app初始化完成以后会触发(全局只会触发一次) |
onShow | 当 uni-app 启动,或从后台进入前台显示 |
onHide | 当 uni-app 从前台进入后台 |
onError | 当 uni-app 报错时触发 |
onUniNViewMessage | 当 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯 |
onUnhandledRejection | 对未处理的 Promise 拒绝事件监听函数 (2.8.1+) |
注意:
1、应用的生命周期函数仅可在 App.vue 中监听,在其他页面监听无效。
2、onlaunch 里进行页面跳转,如遇白屏报错,请参考 https://ask.dcloud.net.cn/article/35942
如下App.vue 中的生命周期函数示例:
页面生命周期:
页面生命周期指的就是单个vue组件中的声明周期,与vue的生命周期混合。
uni-app 支持如下页面生命周期函数:
函数名 | 说明 | 平台差异说明 | 最低版本 |
onLoad | 监听页面加载,其参数为上下页面传递的数据,参数类型为Object (用于页面传参),参考示例 | | |
onShow | 监听页面显示,页面每次出现在屏幕上都触发,包括从下级页面点返回漏出当前页面 | | |
onReady | 监听页面持初次渲染完成。注意:如果渲染速度快,会在页面进入动画完成前触发 | | |
onHide | 监听页面隐藏 | | |
onUnload | 监听页面卸载 | | |
onResize | 监听窗口尺寸变化 | APP、微信小程序 | |
onPullDownRefresh | 监听用户下拉动作,一般用于下拉刷新,参考示例 | | |
onReachBottom | 页面上拉触底事件的处理函数 | | |
onTabitemTap | 点击tab时触发,参数为Object,具体见下方注意事项 | 微信小程序、百度小程序、H5、App(自定义组件模式) | |
onShareAppMessage | 用户点击右上角分享 | 微信小程序、百度小程序、字节跳动小程序、支付宝小程序 | |
onPageScroll | 监听页面滚动,参数为 Object | | |
onNavigationBarButtonTap | 监听原生标题栏按钮点击事件,参数为Object | 5+App 、H5 | |
onBackPress | 监听页面返回,返回 event = { from:backbutton、navigateBack } , backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack 表示来源是 uni.navigateBack;详细说明及使用:onBackPress 详解 | App、H5 | |
onNavigationBarSearchInputChanged | 监听原生标题栏搜索输入框输入内容变化事件 | App、H5 | 1.6.0 |
onNavigationBarSearchInputConfirmed | 监听原生标题栏搜索输入框搜素事件,用户点击软键盘上的“搜索”按钮是触发 | App、H5 | 1.6.0 |
onNavigationBarSearchInputClicked | 监听原生标题栏搜索输入框点击事件 | App、H5 | 1.6.0 |
onShareTimeline | 监听用户点击右上角转发到朋友圈 | 微信小程序 | uni-app 2.8.1+ |
onAddToFavorites | 监听用户点击右上角收藏 | 微信小程序 | uni-app 2.8.1+ |
onPageScroll 参数说明:
属性 | 类型 | 说明 |
scrollTop | Number | 页面在垂直方向已滚动的距离(单位px) |
onTabItemTap 参数说明:
属性 | 类型 | 说明 |
index | String | 被点击tabItem的序号,从0开始 |
pagePath | String | 被点击tabItem的页面路径 |
text | String | 被点击tabItem的按钮文字 |
注意:
1、onTabItemTap 常用于点击当前的 tabItem ,滚动或刷新当前页面。如果是点击不同的tabitem,一定会触发页面切换。
2、如果想在App端实现点击某个 tabItem不跳转页面,不能使用onTabItemTap ,可以使用 plus.nativeObj.view 放一个区块盖住原先的 tabItem ,并拦截点击事件。
3、onTabItemTap 在 App 端,从HBuilder X 1.9 的自定义组件编译模式开始支持。
4、避免在 onShow 里使用需要权限的 API(比如 setScreenBrightness() 等需要手机权限),可能会再次触发 onShow 造成死循环。
onNavigationBarButtonTap 参数说明:
属性 | 类型 | 说明 |
index | Number | 原生标题栏按钮数组的下标 |
onBackPress 回调参数对象说明:
属性 | 类型 | 说明 |
form | String | 触发返回行为的来源:'backbutton'--左上角导航栏按钮及安卓返回键; 'navigateBack'--uni.navigateBack() 方法 |
注意:
nvue 页面支持的声明周期参考:nvue 生命周期介绍
页面中的声明周期示例代码:
me.vue 文件
路由:
uni-app 页面路由为框架统一管理,开发者需要在 pages.json 里配置每个路由页面的路径及页面样式。类似小程序在 app.json 中配置页面路由一样。所以,uni-app 的路由用法 与 Vue Router 不同,如仍希望采用 Vue Router 方式管理路由,可在插件市场搜索 Vue-Router
路由跳转:
uni-app 有两种页面路由跳转方式,一个使用 navigator组件跳转,二是调用 API跳转。
页面栈:
框架以栈的形式管理当前所有页面,当发生路由切换的时候,页面栈的表现如下:
路由方式 | 页面栈表现 | 触发时机 |
初始化 | 新页面入栈 | uni-app 打开的第一个页面 |
打开新页面 | 新页面入栈 | 调用 API uni.navigateTo 或使用组件 <navigator open-type="navigate"/> |
页面重定向 | 当前页面出栈,新页面入栈 | 调用API uni.redirectTo 或使用组件 <navigator open-type="redirectTo"/> |
页面返回 | 页面不断出栈,直到目标返回页 | 调用API uni.navigateBack 或使用组件 <navigator open-type="navigateBack"/>、用户按左上角返回键按钮、安卓用户点击物理 back 按键 |
Tab 切换 | 页面全部出栈,只留下的新的 Tab 页面 | 调用 API uni.switchTab 或使用组件 <navigator open-type="switchTab"/> 、用户切换Tab |
重加载 | 页面全部出栈,只留下新的页面 | 调用 API uni.reLaunch 或者使用组件 <navigator open-type="reLaunch"/> |
运行环境判断:
开发环境和生产环境:
uni-app 可通过 process.env.NODE_ENV 判断当前环境是开发环境还是生产环境。一般用于连接测试服务器还是正式服务器的动态切换。
在 HBuilderX 中,点击“运行” 编译出来的代码的是开发环境,点击“发行” 编译出来的代码是生产环境。
如果你需要自定义更多环境,比如测试环境:
1、 如果你只需要对某一个平台配置,可以在 package.json 中配置,在HBuilderX的运行和发行菜单里会多一个出来,详见 https://uniapp.dcloud.io/collocation/package
2、如果是针对所有平台配置,可以在 vue-config.js 中配置,详见 https://uniapp.dcloud.io/collocation/vue-config
判断平台:
平台判断有2种场景,一种是编译器判断,一种是在运行期判断。
1、编译器判断
编译器判断既是条件编译,不同的平台在编译出包后已经是不同的代码。详见:条件编译
如上代码只会编译到 H5 的发行包 里,其它平台的包不会包含如上代码。
2、运行期判断
运行期判断是指代码已经打入包中,仍然需要在运行期判断平台,此时可使用 uni.getSystemInfoSync().platform 判断客户端环境是 Android、iOS 还是小程序开发工具 (在百度小程序开发工具、微信小程序开发工具、支付宝小程序开发工具中使用 uni.getSystemInfoSync().platform
返回值均为 devtools),如下实例代码:
如有必要,也可以在条件编译里自定义一个变量,赋不同的值,在后续运行代码中动态判断环境。
页面样式与布局:
尺寸单位:
uni-app 支持的通用的 css 单位,包括px、rpx
- px 即屏幕像素
- rpx 即响应式px,一种根据屏幕宽度自适应的动态单位。以750宽的屏幕为基准,750rpx恰好为屏幕的宽度。屏幕变宽,rpx实际显示效果会等比放大。
vue 页面支持普通的 H5 单位,但在 nvue 里不支持:
- rem 默认根字体大小为 屏幕宽度/20(微信小程序、字节跳动小程序、App、H5)
- vh vh是viewpoint height 的缩写,视窗高度, 1vh等于视窗高度的 1%
- vw vw是viewpoint width 的缩写,视窗宽度,1vw 等于视窗宽度的 1%
nvue 还不支持 百分比 单位。
App 端,在pages.json 里的 titleNView 或页面里写 plus api 中涉及的单位,只支持px,不支持rpx。
样式导入:
内联样式:
选择器:
目前支持的选择器有:
选择器 | 样例 | 样例描述 |
.class | .intro | 选择所有拥有 class="intro" 的组件 |
#id | #firstname | 选择拥有 id="firstname" 的组件 |
element | view | 选择所有 view 组件 |
element, element | view, checkbox | 选择所有文档的 view 组件和所有的 checkbox 组件 |
::after | view::after | 在 view 组件后边插入内容,仅微信小程序和App生效 |
::before | view::before | 在 view 组件前边插入内容,仅微信小程序和App生效 |
注意:
- 在
uni-app
中不能使用*
选择器。 -
page
相当于body
节点,例如: - 微信小程序自定义组件中仅支持 class 选择器
全局样式与局部样式:
定义在 App.vue 中的样式为全局样式,作用于每一个页面。
在 pages 目录下的 vue 文件中定义的样式为 局部样式,只作用于对应的页面,并会覆盖 App.vue 中相同的选择器。
注意:
- App.vue 中通过 @import 语句可以导入外联样式,一样作用于没一个页面。
- nvue 页面暂时不支持全局样式
CSS变量:
固定值:
Flex布局:
背景图片:
字体图标:
uni-app
支持使用字体图标,使用方式与普通 web
项目相同,需要注意以下几点:
- 支持 base64 格式字体图标。
- 支持网络路径字体图标。
- 小程序不支持在css中使用本地文件,包括本地的背景图和字体文件。需以base64方式方可使用。App端在v3模式以前,也有相同限制。v3编译模式起支持直接使用本地背景图和字体。
- 网络路径必须加协议头
https
。 - 从http://www.iconfont.cn 上拷贝的代码,默认是没加协议头的。
- 从http://www.iconfont.cn 上下载的字体文件,都是同名字体(字体名都叫iconfont,安装字体文件时可以看到),在nvue内使用时需要注意,此字体名重复可能会显示不正常,可以使用工具修改。
- 使用本地路径图标字体需注意:
- 为方便开发者,在字体文件小于 40kb 时,
uni-app
会自动将其转化为 base64 格式; - 字体文件大于等于 40kb,仍转换为 base64 方式使用的话可能有性能问题,如开发者必须使用,则需自己将其转换为 base64 格式使用,或将其挪到服务器上,从网络地址引用;
- 字体文件的引用路径推荐使用以 ~@ 开头的绝对路径。
nvue
中不可直接使用css的方式引入字体文件,需要使用以下方式在js内引入。nvue内不支持本地路径引入字体,请使用网络链接或者base64
形式。src
字段的url
的括号内一定要使用单引号。
示例:
<template/> 和 <block/>:
globalStyle(全局样式配置):
用于设置应用的状态栏、导航条、标题、窗口背景色等,主要在pages.json中进行配置
pages.json 文件
配置项如下:
属性 | 类型 | 默认值 | 描述 | 平台差异说明 |
navigationBarBackgroundColor | HexColor | #F7F7F7 | 导航栏背景颜色(同状态栏背景色) | APP与H5为#F7F7F7,小程序平台请参考相应小程序文档 |
navigationBarTextStyle | String | white | 导航栏标题颜色及状态栏前景颜色,仅支持 black/white | |
navigationBarTitleText | String | | 导航栏标题文字内容 | |
navigationStyle | String | default | 导航栏样式,仅支持 default/custom。custom即取消默认的原生导航栏,需看使用注意 | 微信小程序 7.0+、百度小程序、H5、App(2.0.3+) |
backgroundColor | HexColor | #ffffff | 下拉显示出来的窗口的背景色 | 微信小程序 |
backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark / light | 微信小程序 |
enablePullDownRefresh | Boolean | false | 是否开启下拉刷新,详见页面生命周期。 | |
onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位只支持px,详见页面生命周期 | |
backgroundColorTop | HexColor | #ffffff | 顶部窗口的背景色(bounce回弹区域) | 仅 iOS 平台 |
backgroundColorBottom | HexColor | #ffffff | 底部窗口的背景色(bounce回弹区域) | 仅 iOS 平台 |
titleImage | String | | 导航栏图片地址(替换当前文字标题),支付宝小程序内必须使用https的图片链接地址 | 支付宝小程序、H5、APP |
transparentTitle | String | none | 导航栏整体(前景、背景)透明设置。支持 always 一直透明 / auto 滑动自适应 / none 不透明 | 支付宝小程序、H5、APP |
titlePenetrate | String | NO | 导航栏点击穿透 | 支付宝小程序、H5 |
pageOrientation | String | portrait | 横屏配置,屏幕旋转设置,仅支持 auto / portrait / landscape 详见 响应显示区域变化 | App 2.4.7+、微信小程序 |
animationType | String | pop-in | 窗口显示的动画效果,详见:窗口动画 | App |
animationDuration | Number | 300 | 窗口显示动画的持续时间,单位为 ms | App |
app-plus | Object | | 设置编译到 App 平台的特定样式,配置项参考下方 app-plus | App |
h5 | Object | | 设置编译到 H5 平台的特定样式,配置项参考下方 H5 | H5 |
mp-alipay | Object | | 设置编译到 mp-alipay 平台的特定样式,配置项参考下方 MP-ALIPAY | 支付宝小程序 |
mp-weixin | Object | | 设置编译到 mp-weixin 平台的特定样式 | 微信小程序 |
mp-baidu | Object | | 设置编译到 mp-baidu 平台的特定样式 | 百度小程序 |
mp-toutiao | Object | | 设置编译到 mp-toutiao 平台的特定样式 | 字节跳动小程序 |
mp-qq | Object | | 设置编译到 mp-qq 平台的特定样式 | QQ小程序 |
usingComponents | Object | | 引用小程序组件,参考 小程序组件 | |
renderingMode | String | | 同层渲染,webrtc(实时音视频) 无法正常时尝试配置 seperated 强制关掉同层 | 微信小程序 |
注意
- 支付宝小程序使用
titleImage
时必须使用https
的图片链接地址,需要真机调试才能看到效果,支付宝开发者工具内无效果 -
globalStyle
中设置的titleImage
也会覆盖掉pages
->style
内的设置文字标题
pages(局部页面样式配置):
uni-app 通过 pages 节点配置应用由哪些页面组成,pages 节点接收一个数组,数组每个项都是一个对象,其属性值如下:
属性 | 类型 | 默认值 | 描述 |
path | String | | 配置页面路径 |
style | Object | | 配置页面窗口表现,配置项参考下方 pageStyle |
注意:
- pages节点的第一项为应用入口页(即首页)
- 应用中新增/减少页面,都需要对 pages 数组进行修改
- 文件名不需要写后缀,框架会自动寻找路径下的页面资源
每新增/减少一个页面,都需要对pages 数组中的对象进行修改
style对象配置
pages对象中的style 对象用于设置每个页面的状态栏、导航栏、标题、窗口背景色等
页面中配置项会覆盖 globalStyle 中相同的配置项,具体配置项如下:
属性 | 类型 | 默认值 | 描述 | 平台差异说明 |
navigationBarBackgroundColor | HexColor | #000000 | 导航栏背景颜色(同状态栏背景色),如"#000000" | |
navigationBarTextStyle | String | white | 导航栏标题颜色及状态栏前景颜色,仅支持 black/white | |
navigationBarTitleText | String | | 导航栏标题文字内容 | |
navigationBarShadow | Object | | 导航栏阴影,配置参考下方 导航栏阴影 | |
navigationStyle | String | default | 导航栏样式,仅支持 default/custom。custom即取消默认的原生导航栏,需看使用注意 | 微信小程序 7.0+、百度小程序、H5、App(2.0.3+) |
disableScroll | Boolean | false | 设置为 true 则页面整体不能上下滚动(bounce效果),只在页面配置中有效,在globalStyle中设置无效 | 微信小程序(iOS)、百度小程序(iOS) |
backgroundColor | HexColor | #ffffff | 窗口的背景色 | 微信小程序、百度小程序、字节跳动小程序 |
backgroundTextStyle | String | dark | 下拉 loading 的样式,仅支持 dark/light | |
enablePullDownRefresh | Boolean | false | 是否开启下拉刷新,详见页面生命周期。 | |
onReachBottomDistance | Number | 50 | 页面上拉触底事件触发时距页面底部距离,单位只支持px,详见页面生命周期 | |
backgroundColorTop | HexColor | #ffffff | 顶部窗口的背景色(bounce回弹区域) | 仅 iOS 平台 |
backgroundColorBottom | HexColor | #ffffff | 底部窗口的背景色(bounce回弹区域) | 仅 iOS 平台 |
titleImage | String | | 导航栏图片地址(替换当前文字标题),支付宝小程序内必须使用https的图片链接地址 | 支付宝小程序、H5 |
transparentTitle | String | none | 导航栏透明设置。支持 always 一直透明 / auto 滑动自适应 / none 不透明 | 支付宝小程序、H5、APP |
titlePenetrate | String | NO | 导航栏点击穿透 | 支付宝小程序、H5 |
app-plus | Object | | 设置编译到 App 平台的特定样式,配置项参考下方 app-plus | App |
h5 | Object | | 设置编译到 H5 平台的特定样式,配置项参考下方 H5 | H5 |
mp-alipay | Object | | 设置编译到 mp-alipay 平台的特定样式,配置项参考下方 MP-ALIPAY | 支付宝小程序 |
mp-weixin | Object | | 设置编译到 mp-weixin 平台的特定样式 | 微信小程序 |
mp-baidu | Object | | 设置编译到 mp-baidu 平台的特定样式 | 百度小程序 |
mp-toutiao | Object | | 设置编译到 mp-toutiao 平台的特定样式 | 字节跳动小程序 |
mp-qq | Object | | 设置编译到 mp-qq 平台的特定样式 | QQ小程序 |
usingComponents | Object | | 引用小程序组件,参考 小程序组件 | App、微信小程序、支付宝小程序、百度小程序 |