UNI-App框架基础部分
文章目录
- 一、全局配置和页面配置
- 二、组件的基本使用
- 三、uni-app中的样式
- 四、数据绑定
- 五、uni中的事件
- 六、uniapp生命周期
- 七、下拉刷新
- 八、网络请求
- 九、数据缓存
- 1.uni.setStorage(OBJECT)
- 2.[#](https://uniapp.dcloud.net.cn/api/storage/storage.html#setstoragesync)uni.setStorageSync(KEY,DATA)
- 3.[#](https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorage)uni.getStorage(OBJECT)
- 4.[#](https://uniapp.dcloud.net.cn/api/storage/storage.html#getstoragesync)uni.getStorageSync(KEY)
- 5.[#](https://uniapp.dcloud.net.cn/api/storage/storage.html#removestorage)uni.removeStorage(OBJECT)
- 6.[#](https://uniapp.dcloud.net.cn/api/storage/storage.html#removestoragesync)uni.removeStorageSync(KEY)
- 十、上传预览
- 十一、条件注释/跨端兼容
- 十二、导航跳转
- 十三、组件的创建
- 十四、组件的通讯
项目结构介绍
pages -------- 存放页面
static ------- 存放静态资源
unpackage -------- 存放打包文件
App.vue -------- 项目的跟组件,所有页面都是在App.vue下进行切换的,页面的入口文件
main.js -------- 项目的入口文件
manifest.json -------- 配置应用打包的
pages.json -------- 设置项目页面的存放路径,项目全局外观
uni.scss -------- 存放一些常用的样式变量
开发规范:
- 页面遵循Vue单文件组件(SFC)规范
- 组件标签靠近小程序规范,详见uni-app组件规范
- 接口能力(JS API)靠近微信小程序规范,但需将前缀wx替换为uni,详见uni-app接口规范
- 数据绑定及时间处理同Vue.js规范马桶是补充了App及页面的生命周期
- 为兼容多端运行梦见一使用flex布局进行开发
一、全局配置和页面配置
1.globalStyle全局外观配置
**【官方文档】**用于设置应用的状态栏、导航条、标题、窗口背景色等。
属性 | 类型 | 默认值 | 描述 | 平台差异说明 |
---|---|---|---|---|
navigationBarBackgroundColor | HexColor | #F8F8F8 | 导航栏背景颜色(同状态栏背景色) | APP与H5为#F8F8F8,小程序平台请参考相应小程序文档 |
navigationBarTextStyle | String | black | 导航栏标题颜色及状态栏前景颜色,仅支持 black/white | 支付宝小程序不支持,请使用 my.setNavigationBar |
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+、微信小程序、QQ小程序 |
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-WEIXIN | 微信小程序 | |
mp-baidu | Object | 设置编译到 mp-baidu 平台的特定样式,配置项参考下方 MP-BAIDU | 百度小程序 | |
mp-toutiao | Object | 设置编译到 mp-toutiao 平台的特定样式 | 抖音小程序 | |
mp-lark | Object | 设置编译到 mp-lark 平台的特定样式 | 飞书小程序 | |
mp-qq | Object | 设置编译到 mp-qq 平台的特定样式 | QQ小程序 | |
mp-kuaishou | Object | 设置编译到 mp-kuaishou 平台的特定样式 | 快手小程序 | |
mp-jd | Object | 设置编译到 mp-jd 平台的特定样式 | 京东小程序 | |
usingComponents | Object | 引用小程序组件,参考 小程序组件 | ||
renderingMode | String | 同层渲染,webrtc(实时音视频) 无法正常时尝试配置 seperated 强制关掉同层 | 微信小程序 | |
leftWindow | Boolean | true | 当存在 leftWindow 时,默认是否显示 leftWindow | H5 |
topWindow | Boolean | true | 当存在 topWindow 时,默认是否显示 topWindow | H5 |
rightWindow | Boolean | true | 当存在 rightWindow 时,默认是否显示 rightWindow | H5 |
rpxCalcMaxDeviceWidth | Number | 960 | rpx 计算所支持的最大设备宽度,单位 px | App(vue2 且不含 nvue)、H5(2.8.12+) |
rpxCalcBaseDeviceWidth | Number | 375 | rpx 计算使用的基准设备宽度,设备实际宽度超出 rpx 计算所支持的最大设备宽度时将按基准宽度计算,单位 px | App(vue2 且不含 nvue)、H5(2.8.12+) |
rpxCalcIncludeWidth | Number | 750 | rpx 计算特殊处理的值,始终按实际的设备宽度计算,单位 rpx | App(vue2 且不含 nvue)、H5(2.8.12+) |
dynamicRpx | Boolean | false | 动态 rpx,屏幕大小变化会重新渲染 rpx | App-nvue(vue3 固定值为 true) 3.2.13+ |
maxWidth | Number | 单位px,当浏览器可见区域宽度大于maxWidth时,两侧留白,当小于等于maxWidth时,页面铺满;不同页面支持配置不同的maxWidth;maxWidth = leftWindow(可选)+page(页面主体)+rightWindow(可选) | H5(2.9.9+) |
注意
- 支付宝小程序使用
titleImage
时必须使用https
的图片链接地址,需要真机调试才能看到效果,支付宝开发者工具内无效果 globalStyle
中设置的titleImage
也会覆盖掉pages
->style
内的设置文字标题- 使用
maxWidth
时,页面内fixed元素需要使用–window-left,–window-right来保证布局位置正确 dynamicRpx
vue3 nvue页面已移除此配置,升级为横竖屏切换自动rpx,如果不需要可以使用 px
示例:
"globalStyle": {
"navigationBarTextStyle": "white", //标题颜色
"navigationBarTitleText": "绿帽子", // 标题文字(全局的)
"navigationBarBackgroundColor": "#00ff00", //导航栏背景颜色
"backgroundColor": "#aaaa00", // 下拉区域背景颜色
"enablePullDownRefresh": true, //是否开启下拉刷新
"backgroundTextStyle": "light" ,// 下拉loding的演示,仅支持dark/light
}
2.page配置
uni-app
通过 pages 节点配置应用由哪些页面组成,pages 节点接收一个数组,数组每个项都是一个对象,其属性值如下:
属性 | 类型 | 默认值 | 描述 |
---|---|---|---|
path | String | 配置页面路径 | |
style | Object | 配置页面窗口表现,配置项参考下方 pageStyle | |
needLogin | Boolean | false | 是否需要登录才可访问 |
Tips:
- pages节点的第一项为应用入口页(即首页)
- 应用中新增/减少页面,都需要对 pages 数组进行修改
- 文件名不需要写后缀,框架会自动寻找路径下的页面资源
style
用于设置每个页面的状态栏、导航条、标题、窗口背景色等。
页面中配置项会覆盖 globalStyle 中相同的配置项
注意
- 使用
maxWidth
时,页面内fixed元素需要使用–window-left,–window-right来保证布局位置正确
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "主页",
"navigationBarBackgroundColor": "#00ff7f", //导航栏背景颜色
"h5": { //配置在H5页面编译的样式
"titleNView": {
"titleColor": "write"
}
}
}
}
3.tabbar配置
如果应用是一个多 tab 应用,可以通过 tabBar 配置项指定一级导航栏,以及 tab 切换时显示的对应页。
Tips
- 当设置 position 为 top 时,将不会显示 icon
- tabBar 中的 list 是一个数组,只能配置最少2个、最多5个 tab,tab 按数组的顺序排序。
- tabbar 切换第一次加载时可能渲染不及时,可以在每个tabbar页面的onLoad生命周期里先弹出一个等待雪花(hello uni-app使用了此方式)
- tabbar 的页面展现过一次后就保留在内存中,再次切换 tabbar 页面,只会触发每个页面的onShow,不会再触发onLoad。
- 顶部的 tabbar 目前仅微信小程序上支持。需要用到顶部选项卡的话,建议不使用 tabbar 的顶部设置,而是自己做顶部选项卡,可参考 hello uni-app->模板->顶部选项卡。
属性说明:
属性 | 类型 | 必填 | 默认值 | 描述 | 平台差异说明 |
---|---|---|---|---|---|
color | HexColor | 是 | tab 上的文字默认颜色 | ||
selectedColor | HexColor | 是 | tab 上的文字选中时的颜色 | ||
backgroundColor | HexColor | 是 | tab 的背景色 | ||
borderStyle | String | 否 | black | tabbar 上边框的颜色,可选值 black/white,也支持其他颜色值 | App 2.3.4+ 、H5 3.0.0+ |
blurEffect | String | 否 | none | iOS 高斯模糊效果,可选值 dark/extralight/light/none(参考:使用说明) | App 2.4.0+ 支持、H5 3.0.0+(只有最新版浏览器才支持) |
list | Array | 是 | tab 的列表,详见 list 属性说明,最少2个、最多5个 tab | ||
position | String | 否 | bottom | 可选值 bottom、top | top 值仅微信小程序支持 |
fontSize | String | 否 | 10px | 文字默认大小 | App 2.3.4+、H5 3.0.0+ |
iconWidth | String | 否 | 24px | 图标默认宽度(高度等比例缩放) | App 2.3.4+、H5 3.0.0+ |
spacing | String | 否 | 3px | 图标和文字的间距 | App 2.3.4+、H5 3.0.0+ |
height | String | 否 | 50px | tabBar 默认高度 | App 2.3.4+、H5 3.0.0+ |
midButton | Object | 否 | 中间按钮 仅在 list 项为偶数时有效 | App 2.3.4+、H5 3.0.0+ | |
iconfontSrc | String | 否 | list设置 iconfont 属性时,需要指定字体文件路径 | App 3.4.4+、H5 3.5.3+ | |
backgroundImage | String | 否 | 设置背景图片,优先级高于 backgroundColor | App | |
backgroundRepeat | String | 否 | 设置标题栏的背景图平铺方式,可取值:“repeat” - 背景图片在垂直方向和水平方向平铺;“repeat-x” - 背景图片在水平方向平铺,垂直方向拉伸;“repeat-y” - 背景图片在垂直方向平铺,水平方向拉伸;“no-repeat” - 背景图片在垂直方向和水平方向都拉伸。 默认使用 “no-repeat” | App | |
redDotColor | String | 否 | tabbar上红点颜色 | App |
其中 list 接收一个数组,数组中的每个项都是一个对象,其属性值如下:
属性 | 类型 | 必填 | 说明 | 平台差异 |
---|---|---|---|---|
pagePath | String | 是 | 页面路径,必须在 pages 中先定义 | |
text | String | 是 | tab 上按钮文字,在 App 和 H5 平台为非必填。例如中间可放一个没有文字的+号图标 | |
iconPath | String | 否 | 图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px,当 position 为 top 时,此参数无效,不支持网络图片,不支持字体图标 | |
selectedIconPath | String | 否 | 选中时的图片路径,icon 大小限制为40kb,建议尺寸为 81px * 81px ,当 position 为 top 时,此参数无效 | |
visible | Boolean | 否 | 该项是否显示,默认显示 | App (3.2.10+)、H5 (3.2.10+) |
iconfont | Object | 否 | 字体图标,优先级高于 iconPath | App(3.4.4+)、H5 (3.5.3+) |
midButton 属性说明
属性 | 类型 | 必填 | 默认值 | 描述 | |
---|---|---|---|---|---|
width | String | 否 | 80px | 中间按钮的宽度,tabBar 其它项为减去此宽度后平分,默认值为与其它项平分宽度 | |
height | String | 否 | 50px | 中间按钮的高度,可以大于 tabBar 高度,达到中间凸起的效果 | |
text | String | 否 | 中间按钮的文字 | ||
iconPath | String | 否 | 中间按钮的图片路径 | ||
iconWidth | String | 否 | 24px | 图片宽度(高度等比例缩放) | |
backgroundImage | String | 否 | 中间按钮的背景图片路径 | ||
iconfont | Object | 否 | 字体图标,优先级高于 iconPath | App(3.4.4+) |
代码示例:
"tabBar": {
"color": "#A0522D", //未选中的文字颜色
"selectedColor": "#B3EE3A", // 选中的文字颜色
"backgroundColor": "#FFFFFF", // 按钮背景色、
"borderStyle": "black", //上边框的颜色
"position": "bottom", // 底部信息栏或者顶部信息栏位置
//只有bottom 和top 设置top时候图标不显示,只在小程序中生效
"list": [{
"text": "首页", //文字
"pagePath": "pages/index/index", //页面路径
"iconPath": "static/tabs/home.png", //默认没选中的
"selectedIconPath": "static/tabs/home-active.png" //选中的
},
{
"text": "信息", //文字
"pagePath": "pages/massage/massage", //页面路径
"iconPath": "static/tabs/message.png", //默认没选中的
"selectedIconPath": "static/tabs/message-active.png" //选中的
},
{
"text": "我们", //文字
"pagePath": "pages/contact/contact", //页面路径
"iconPath": "static/tabs/contact.png", //默认没选中的
"selectedIconPath": "static/tabs/contact-active.png" //选中的
}
]
}
4.condition启动模式配置
启动模式配置,仅开发期间生效,用于模拟直达页面的场景,如:小程序转发后,用户点击所打开的页面。
属性说明:
属性 | 类型 | 是否必填 | 描述 |
---|---|---|---|
current | Number | 是 | 当前激活的模式,list节点的索引值 |
list | Array | 是 | 启动模式列表 |
list说明:
属性 | 类型 | 是否必填 | 描述 |
---|---|---|---|
name | String | 是 | 启动模式名称 |
path | String | 是 | 启动页面路径 |
query | String | 否 | 启动参数,可在页面的 onLoad 函数里获得 |
注意: 在 App 里真机运行可直接打开配置的页面,微信开发者工具里需要手动改变编译模式,如下图:
示例代码:
"condition": { // 在微信开发者工具中添加了编译模式
"current": 0,
"list": [{
"name": "详情页", // 编译名称
"path": "pages/detail/detail", // 编译页面路径
"query": "id=80" //编译参数
}]
}
二、组件的基本使用
1.text组件文本组件
文本组件。用于包裹文本内容。
在app-uvue和app-nvue中,文本只能写在text中,而不能写在view的text区域。
虽然app-uvue中写在view的text区域的文字,也会被编译器自动包裹一层text组件,看起来也可以使用。但这样会造成无法修改该text文字的样式,详见uvue的样式不继承章节
#属性说明
属性名 | 类型 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|
selectable | Boolean | false | 文本是否可选 | |
user-select | Boolean | false | 文本是否可选 | 微信小程序 |
space | String | 显示连续空格 | 钉钉小程序不支持 | |
decode | Boolean | false | 是否解码 | 百度、钉钉小程序不支持 |
space 值说明
值 | 说明 |
---|---|
ensp | 中文字符空格一半大小 |
emsp | 中文字符空格大小 |
nbsp | 根据字体设置的空格大小 |
#子组件
text组件在web浏览器渲染(含浏览器、小程序webview渲染模式、app-vue)和uvue中,可以并只能嵌套text组件。
在nvue中,text组件不能嵌套。
#Tips
- 支持
\n
方式换行。 - 在app-nvue下,只有
<text>
才能包裹文本内容。无法在<view>
组件包裹文本。 - decode 可以解析的有
<
>
&
'
- 各个操作系统的空格标准并不一致。
- 除了文本节点以外的其他节点都无法长按选中。
- 如果使用
<span>
组件编译时会被转换为<text>
。 - nvue 样式
word-wrap
在 Android 平台暂不支持
示例代码
<view>
<view>
<text>唱歌跳舞篮球</text>
</view>
<view>
<text selectable>唱歌跳舞篮球</text>
</view>
<view>
<text space="ensp">唱歌 篮球 中文字符空格一半大小</text>
</view>
<view>
<text space="emsp">唱歌 篮球 中文字符空格大小</text>
</view>
<view>
<text space="nbsp">唱歌 篮球 根据字体设置的空格大小</text>
</view>
<view>
<text decode="true"> </text>
</view>
</view>
2.view组件
视图容器。
它类似于传统html中的div,用于包裹各种元素内容。
如果使用nvue,则需注意,包裹文字应该使用<text>
组件。
属性说明
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
hover-class | String | none | 指定按下去的样式类。当 hover-class=“none” 时,没有点击态效果 |
hover-stop-propagation | Boolean | false | 指定是否阻止本节点的祖先节点出现点击态,App、H5、支付宝小程序、百度小程序不支持(支付宝小程序、百度小程序文档中都有此属性,实测未支持) |
hover-start-time | Number | 50 | 按住后多久出现点击态,单位毫秒 |
hover-stay-time | Number | 400 | 手指松开后点击态保留时间,单位毫秒 |
示例代码
<view class="box2" hover-class="box2-active">
<view class="box" :hover-stay-time="2000" :hover-start-time="2000" hover-class="box-active"
hover-stop-propagation="true"></view>
</view>
<style>
.box {
width: 100px;
height: 100px;
background-color: green;
}
.box-active {
/* 点击后发生的变化 */
background-color: red;
}
.box2 {
width: 200px;
height: 200px;
background-color: blue;
}
.box2-active {
background-color: pink;
}
</style>
3.Bottom组件
属性说明
属性名 | 类型 | 默认值 | 说明 | 生效时机 | 平台差异说明 |
---|---|---|---|---|---|
size | String | default | 按钮的大小 | ||
type | String | default | 按钮的样式类型 | ||
plain | Boolean | false | 按钮是否镂空,背景色透明 | ||
disabled | Boolean | false | 是否禁用 | ||
loading | Boolean | false | 名称前是否带 loading 图标 | H5、App(App-nvue 平台,在 ios 上为雪花,Android上为圆圈) | |
form-type | String | 用于 <form> 组件,点击分别会触发 <form> 组件的 submit/reset 事件 | |||
open-type | String | 开放能力 | |||
hover-class | String | button-hover | 指定按钮按下去的样式类。当 hover-class=“none” 时,没有点击态效果 | App-nvue 平台暂不支持 | |
hover-start-time | Number | 20 | 按住后多久出现点击态,单位毫秒 | ||
hover-stay-time | Number | 70 | 手指松开后点击态保留时间,单位毫秒 | ||
app-parameter | String | 打开 APP 时,向 APP 传递的参数,open-type=launchApp时有效 | 微信小程序、QQ小程序 | ||
hover-stop-propagation | boolean | false | 指定是否阻止本节点的祖先节点出现点击态 | 微信小程序 | |
lang | string | ‘en’ | 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文。 | 微信小程序 | |
session-from | string | 会话来源,open-type="contact"时有效 | 微信小程序 | ||
send-message-title | string | 当前标题 | 会话内消息卡片标题,open-type="contact"时有效 | 微信小程序 | |
send-message-path | string | 当前分享路径 | 会话内消息卡片点击跳转小程序路径,open-type="contact"时有效 | 微信小程序 | |
send-message-img | string | 截图 | 会话内消息卡片图片,open-type="contact"时有效 | 微信小程序 | |
show-message-card | boolean | false | 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,open-type="contact"时有效 | 微信小程序 | |
group-id | String | 打开群资料卡时,传递的群号 | open-type=“openGroupProfile” | QQ小程序 | |
guild-id | String | 打开频道页面时,传递的频道号 | open-type=“openGuildProfile” | QQ小程序 | |
public-id | String | 打开公众号资料卡时,传递的号码 | open-type=“openPublicProfile” | QQ小程序 | |
data-im-id | String | 客服的抖音号 | open-type=“im” | 抖音小程序2.68.0版本+ | |
data-im-type | String | IM卡片类型 | open-type=“im” | 抖音小程序2.80.0版本+ | |
data-goods-id | String | 商品的id,仅支持泛知识课程库和生活服务商品库中的商品 | open-type=“im” | 抖音小程序2.80.0版本+ | |
data-order-id | String | 订单的id,仅支持交易2.0订单 | open-type=“im” | 抖音小程序2.80.0版本+ | |
data-biz-line | String | 商品类型,“1”代表生活服务,“2”代表泛知识。 | open-type=“im” | 抖音小程序2.80.0版本+ | |
@getphonenumber | Handler | 获取用户手机号回调 | open-type=“getPhoneNumber” | 微信、支付宝、百度、抖音、快手、京东小程序 | |
@getuserinfo | Handler | 用户点击该按钮时,会返回获取到的用户信息,从返回参数的detail中获取到的值同uni.getUserInfo | open-type=“getUserInfo” | 微信、QQ、百度、快手、京东小程序 | |
@error | Handler | 当使用开放能力时,发生错误的回调 | open-type=“launchApp” | 微信、QQ、快手、京东小程序 | |
@opensetting | Handler | 在打开授权设置页并关闭后回调 | open-type=“openSetting” | 微信、QQ、百度、快手、京东小程序 | |
@launchapp | Handler | 从小程序打开 App 成功的回调 | open-type=“launchApp” | 微信、QQ、快手、京东小程序 | |
@contact | Handler | 客服消息回调 | open-type=“contact” | 微信、QQ、百度、快手小程序 | |
@chooseavatar | Handler | 获取用户头像回调 | open-type=“chooseAvatar” | 微信小程序 | |
@agreeprivacyauthorization | Handler | 用户同意隐私协议事件回调,open-type="agreePrivacyAuthorization"时有效 | open-type=“agreeprivacyauthorization” | 微信小程序2.33.0 | |
@addgroupapp | Handler | 添加群应用的回调 | open-type=“addGroupApp” | QQ小程序 | |
@chooseaddress | Handler | 调起用户编辑并选择收货地址的回调 | open-type=“chooseAddress” | 百度小程序 | |
@chooseinvoicetitle | Handler | 用户选择发票抬头的回调 | open-type=“chooseInvoiceTitle” | 百度小程序 | |
@subscribe | Handler | 订阅消息授权回调 | open-type=“subscribe” | 百度小程序 | |
@login | Handler | 登录回调 | open-type=“login” | 百度小程序 | |
@im | Handler | 监听跳转IM的成功回调 | open-type=“im” | 抖音小程序2.68.0版本+ |
- 注1:
button-hover
默认为{background-color: rgba(0, 0, 0, 0.1); opacity: 0.7;}
open-type="launchApp"
时需要调起的APP接入微信OpenSDK详见- 微信小程序、Web、App平台 button组件的默认边框宽度为0.5px,不会占据实际的渲染宽高;当type属性为plain时,边框宽度是1px,如果未指定元素的宽高,此时边框宽度会占据实际渲染宽高。
#size 有效值
值 | 说明 |
---|---|
default | 默认大小 |
mini | 小尺寸 |
button组件也支持style中通过css定义文字大小。见下
#type 有效值
值 | 说明 |
---|---|
primary | 微信小程序、360小程序为绿色,App、H5、百度小程序、支付宝小程序、飞书小程序、快应用为蓝色,抖音小程序为红色,QQ小程序为浅蓝色。如想在多端统一颜色,请改用default,然后自行写样式 |
default | 白色 |
warn | 红色 |
button组件也支持style中通过css定义颜色。
代码示例
<button size="mini">按钮</button>
<button>按钮</button>
<button type="primary">绿色</button>
<button type="warn">红色</button>
<button plain type="primary">镂空</button>
<button disabled>禁用</button>
<button loading>加载</button>
4.image组件
图片组件。
属性名 | 类型 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|
src | String | 图片资源地址 | ||
mode | String | ‘scaleToFill’ | 图片裁剪、缩放的模式 | |
lazy-load | Boolean | false | 图片懒加载。只针对page与scroll-view下的image有效 | 微信小程序、百度小程序、抖音小程序、飞书小程序 |
fade-show | Boolean | true | 图片显示动画效果 | 仅App-nvue 2.3.4+ Android有效 |
webp | boolean | false | 在系统不支持webp的情况下是否单独启用webp。默认false,只支持网络资源。webp支持详见下面说明 | 微信小程序2.9.0 |
show-menu-by-longpress | boolean | false | 开启长按图片显示识别小程序码菜单 | 微信小程序2.7.0 |
draggable | boolean | true | 是否能拖动图片 | H5 3.1.1+、App(iOS15+) |
@error | HandleEvent | 当错误发生时,发布到 AppService 的事件名,事件对象event.detail = {errMsg: ‘something wrong’} | ||
@load | HandleEvent | 当图片载入完毕时,发布到 AppService 的事件名,事件对象event.detail = {height:‘图片高度px’, width:‘图片宽度px’} |
#图片格式说明:
- 当使用浏览器/webview渲染时,支持哪些图片格式由webview决定,详见
- 当使用uvue原生渲染时支持的格式如下
- bmp
- gif
- ico
- jpg
- png
- webp
- heic(Android10+支持)
- avif
- tif
- svg
- 可以通过插件来扩展app平台nvue/uvue的图片支持,比如插件市场搜索svg插件
- 小程序上只支持网络地址的svg图
- webp图片支持详解
- Android4以上(含)、iOS14以上(含)系统内置支持webp,此时,不管web、小程序、app,也不管vue/nvue/uvue都可以直接使用webp;
- iOS14以下,app-vue下,iOS不支持;app-nvue/uvue下,iOS支持;微信小程序2.9.0起,配置属性webp为true时iOS支持;
- pc浏览器上,webp在不同浏览器的支持详见:https://caniuse.com/?search=webp
Tips
<image>
组件未设置宽高时,默认宽度320px、高度240px。尤其注意当图片加载失败时,widthFix模式指定宽度的图片,虽然图片空白,但其高度会变成240px;app-nvue平台,暂时默认为屏幕宽度、高度 240px;
src
仅支持相对路径、绝对路径,支持 base64 码;- 页面结构复杂,css样式太多的情况,使用 image 可能导致样式生效较慢,出现 “闪一下” 的情况,此时设置
image{will-change: transform}
,可优化此问题。 - 自定义组件里面使用
<image>
时,若src
使用相对路径可能出现路径查找失败的情况,故建议使用绝对路径。
#mode 有效值
mode 有 14 种模式,其中 5 种是缩放模式,9 种是裁剪模式。
模式 | 值 | 说明 |
---|---|---|
缩放 | scaleToFill | 不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素 |
缩放 | aspectFit | 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。 |
缩放 | aspectFill | 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。 |
缩放 | widthFix | 宽度不变,高度自动变化,保持原图宽高比不变 |
缩放 | heightFix | 高度不变,宽度自动变化,保持原图宽高比不变 App 和 H5 平台 HBuilderX 2.9.3+ 支持、微信小程序需要基础库 2.10.3 |
裁剪 | top | 不缩放图片,只显示图片的顶部区域 |
裁剪 | bottom | 不缩放图片,只显示图片的底部区域 |
裁剪 | center | 不缩放图片,只显示图片的中间区域 |
裁剪 | left | 不缩放图片,只显示图片的左边区域 |
裁剪 | right | 不缩放图片,只显示图片的右边区域 |
裁剪 | top left | 不缩放图片,只显示图片的左上边区域 |
裁剪 | top right | 不缩放图片,只显示图片的右上边区域 |
裁剪 | bottom left | 不缩放图片,只显示图片的左下边区域 |
裁剪 | bottom right | 不缩放图片,只显示图片的右下边区域 |
示例代码
<!-- 默认宽度320px 高度240px 超出会造成缩放-->
<image src="https://pic.ibaotu.com/01/41/88/888piC1R888piCwD7.jpg-0.jpg!cg845"></image>
<!-- 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。 -->
<image mode="aspectFill" src="https://pic.ibaotu.com/01/41/88/888piC1R888piCwD7.jpg-0.jpg!cg845"></image>
<!-- 保持纵横比缩放图片,使图片的长边可以显示出来 -->
<image mode="aspectFit" src="https://pic.ibaotu.com/01/41/88/888piC1R888piCwD7.jpg-0.jpg!cg845"></image>
三、uni-app中的样式
uni-app 支持less、sass、scss、stylus等预处理器。
尺寸单位
uni-app
支持的通用 css 单位包括 px、rpx
- px 即屏幕像素
- rpx 即响应式 px,一种根据屏幕宽度自适应的动态单位。以 750 宽的屏幕为基准,**750rpx 恰好为屏幕宽度。**屏幕变宽,rpx 实际显示效果会等比放大,但在 App(vue2 不含 nvue) 端和 H5(vue2) 端屏幕宽度达到 960px 时,默认将按照 375px 的屏幕宽度进行计算,具体配置参考:rpx 计算配置 。
vue 页面支持下面这些普通 H5 单位,但在 nvue 里不支持:
- rem 根字体大小可以通过 page-meta 配置抖音小程序和飞书小程序:屏幕宽度/20、百度小程序:16px、支付宝小程序:50px
- vh viewpoint height,视窗高度,1vh 等于视窗高度的 1%
- vw viewpoint width,视窗宽度,1vw 等于视窗宽度的 1%
四、数据绑定
1.插值
数据绑定最常见的形式就是文本插值:
<template>
<view>
<view>Message: {{ msg }}</view>
</view>
</template>
<script>
export default {
data() {
return {
msg: 'Hello Vue!'
}
}
}
</script>
复制代码
里的内容将会被替代为对应数据对象上msg的值。无论何时,绑定的数据对象上msg发生了改变,插值处的内容都会更新。
#使用 JavaScript 表达式
迄今为止,在我们的模板中,我们一直都只绑定简单的 property
键值。但实际上,对于所有的数据绑定,Vue.js 都提供了完全的 JavaScript
表达式支持。
<template>
<view>
<view>{{ number + 1 }}</view>
<view>{{ ok ? 'YES' : 'NO' }}</view>
<!-- 把一个字符串分割成字符串数组,颠倒其元素的顺序,把数组中的所有元素放入一个字符串 -->
<view>{{ message.split('').reverse().join('') }}</view>
</view>
</template>
<script>
export default {
data() {
return {
number:1,
ok:true,
message: 'Hello Vue!'
}
}
}
</script>
<template>
<view>
<view v-for="(item,index) in 10">
<!-- 通过%运算符求余数,实现隔行换色的效果 -->
<view :class="'list-' + index%2">{{index%2}}</view>
</view>
</view>
</template>
<script>
export default {
data() {
return { }
}
}
</script>
<style>
.list-0{
background-color: #aaaaff;
}
.list-1{
background-color: #ffaa7f;
}
</style>
这些表达式会在所属 Vue 实例的数据作用域下作为 JavaScript
被解析。有个限制就是,每个绑定都只能包含单个表达式,所以下面的例子都不会生效。
2.v-bind
动态地绑定一个或多个属性,或一个组件 prop
到表达式。
- v-bind缩写为‘ : ’
- 在绑定
prop
时,prop
必须在子组件中声明。 - 可以用修饰符指定不同的绑定类型。
<image v-bind:src="imgUrl"></image>
<!-- 缩写 -->
<image :src="imgUrl"></image>
<!-- prop 绑定。“prop”必须在 my-component 中声明。-->
<my-component :prop="someThing"></my-component>
<button v-bind:disabled="isButtonDisabled">Button</button>
复制代码
如果 isButtonDisabled
的值是 null
、undefined
或 false
,则 disabled
甚至不会被包含在渲染出来的 button
元素中。
#v-on
v-on 指令,它用于监听 DOM 事件。v-on缩写为‘ @ ’,下文简称为 @事件
<!-- 完整语法 -->
<view v-on:click="doSomething">点击</view>
<!-- 缩写 -->
<view @click="doSomething">点击</view>
3.v-for
在 v-for 里使用数组
v-for 指令可以实现基于一个数组来渲染一个列表。
-
v-for
指令需要使用
item in items
形式的特殊语法,其中
items
是源数据数组,而
item
则是被迭代的数组元素的别名。
- 第一个参数
item
则是被迭代的数组元素的别名。 - 第二个参数,即当前项的索引
index
,是可选的。
- 第一个参数
<template>
<view>
<view v-for="(item, index) in items">
{{ index }} - {{ item.message }}
</view>
</view>
</template>
<script>
export default {
data() {
return {
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
}
}
</script>
结果:
0 - Foo
1 - Bar
#在 v-for 里使用对象
你也可以用 v-for 来遍历一个对象的 property
。
- 第一个参数
value
是被迭代的对象元素的属性值。 - 第二个参数为
property
名称 (也就是键名)。 - 第三个参数作为索引。
<template>
<view>
<view v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</view>
</view>
</template>
<script>
export default {
data() {
return {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2020-04-10'
}
}
}
}
</script>
结果:
0.title: How to do lists in Vue,
1.author: Jane Doe,
2.publishedAt: 2020-04-10
#列表渲染分组
类似于 v-if
,你也可以利用带有 v-for
的 template
来循环渲染一段包含多个元素的内容。比如:
<template v-for="item in items">
<view>{{ item.message }}</view>
<view class="divider" role="presentation"></view>
</template>
复制代码
#key
当 Vue 正在更新使用 v-for
渲染的元素列表时,它默认使用“就地更新”的策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序,而是就地更新每个元素,并且确保它们在每个索引位置正确渲染。
如果列表中项目的位置会动态改变或者有新的项目添加到列表中,并且希望列表中的项目保持自己的特征和状态(如 input
中的输入内容,switch
的选中状态),需要使用 :key
来指定列表中项目的唯一的标识符。
:key
的值以两种形式提供
- 使用
v-for
循环array
中item
的某个property
,该property
的值需要是列表中唯一的字符串或数字,且不能动态改变。 - 使用
v-for
循环中item
本身,这时需要item
本身是一个唯一的字符串或者数字
当数据改变触发渲染层重新渲染的时候,会校正带有 key 的组件,框架会确保他们被重新排序,而不是重新创建,以确保使组件保持自身的状态,并且提高列表渲染时的效率。
如不提供 :key,会报一个
warning
, 如果明确知道该列表是静态,或者不必关注其顺序,可以选择忽略。
示例:
<template>
<view>
<!-- array 中 item 的某个 property -->
<view v-for="(item,index) in objectArray" :key="item.id">
{{index +':'+ item.name}}
</view>
<!-- item 本身是一个唯一的字符串或者数字时,可以使用 item 本身 -->
<view v-for="(item,index) in stringArray" :key="item">
{{index +':'+ item}}
</view>
</view>
</template>
<script>
export default {
data () {
return {
objectArray:[{
id:0,
name:'li ming'
},{
id:1,
name:'wang peng'
}],
stringArray:['a','b','c']
}
}
}
</script>
#注意事项
- 在H5平台 使用 v-for 循环整数时和其他平台存在差异,如
v-for="(item, index) in 10"
中,在H5平台 item 从 1 开始,其他平台 item 从 0 开始,可使用第二个参数 index 来保持一致。 - 在非H5平台 循环对象时不支持第三个参数,如
v-for="(value, name, index) in object"
中,index 参数是不支持的。 - 小程序端数据为差量更新方式,由于小程序不支持删除对象属性,使用的设置值为 null 的方式替代,导致遍历时可能出现不符合预期的情况,需要自行过滤一下值为 null 的数据(相关反馈)。
#在组件上使用 v-for
在自定义组件上,你可以像在任何普通元素上一样使用 v-for
。
<my-component v-for="item in items" :key="item.id"></my-component>
当在组件上使用 v-for 时,key是必须的。
五、uni中的事件
1.v-on事件绑定
v-on 指令,它用于监听 DOM 事件。v-on缩写为‘ @ ’,下文简称为 @事件
<!-- 完整语法 -->
<view v-on:click="doSomething">点击</view>
<!-- 缩写 -->
<view @click="doSomething">点击</view>
事件传参
<button type="primary" v-on:click="clickHandle(10,$event)">按钮</button>
methods: {
clickHandle(num, e) { //e -- $event是事件对象
console.log(num, e)
}
},
六、uniapp生命周期
1.应用的生命周期
生命周期的概念:一个对象从创建、运行、销毁的整个过程被称为生命周期
生命周期函数:在生命周期中每个阶段会伴随着每一个函数的出发,这些函数被称为生命周期函数
所有页面都是在App.vue
下进行切换的,是应用入口文件。但App.vue
本身不是页面,这里不能编写视图元素,也就是没有<template>
。
这个文件的作用包括:监听应用生命周期、配置全局样式、配置全局的存储globalData
应用生命周期仅可在App.vue
中监听,在页面监听无效。
uni-app
支持如下应用生命周期函数:
函数名 | 说明 | 平台兼容 |
---|---|---|
onLaunch | 当uni-app 初始化完成时触发(全局只触发一次),参数为应用启动参数,同 uni.getLaunchOptionsSync 的返回值 | |
onShow | 当 uni-app 启动,或从后台进入前台显示,参数为应用启动参数,同 uni.getLaunchOptionsSync 的返回值 | |
onHide | 当 uni-app 从前台进入后台 | |
onError | 当 uni-app 报错时触发 | app-uvue 不支持 |
onUniNViewMessage | 对 nvue 页面发送的数据进行监听,可参考 nvue 向 vue 通讯 | app-uvue 不支持 |
onUnhandledRejection | 对未处理的 Promise 拒绝事件监听函数(2.8.1+ app-uvue 暂不支持) | app-uvue 不支持 |
onPageNotFound | 页面不存在监听函数 | app-uvue 不支持 |
onThemeChange | 监听系统主题变化 | app-uvue 不支持 |
onLastPageBackPress | 最后一个页面按下Android back键,常用于自定义退出 | app-uvue-android 3.9+ |
onExit | 监听应用退出 | app-uvue-android 3.9+ |
示例代码
<script>
// 只能在App.vue里监听应用的生命周期
export default {
onLaunch: function(options) { // 初始化完成出发
console.log('App Launch')
console.log('应用启动路径:', options.path)
},
onShow: function(options) { // 显示成功会出发
console.log('App Show')
console.log('应用启动路径:', options.path)
},
onHide: function() {// 从前台进入后台 (隐藏会出发)
console.log('App Hide')
},
onError: function() {// 报错时候触发
console.log('App onError')
}
}
</script>
注意
- 应用生命周期仅可在
App.vue
中监听,在其它页面监听无效。 - 以组合式 API 使用时,在 Vue2 和 Vue3 中存在一定区别,请分别参考:Vue2 组合式 API 使用文档 和 Vue3 组合式 API 使用文档。
- 应用启动参数,可以在API
uni.getLaunchOptionsSync
获取,详见 - onlaunch里进行页面跳转,如遇白屏报错,请参考https://ask.dcloud.net.cn/article/35942
App.vue
不能写模板- onPageNotFound 页面实际上已经打开了(比如通过分享卡片、小程序码)且发现页面不存在,才会触发,api 跳转不存在的页面不会触发(如 uni.navigateTo)
2.页面的生命周期
uni-app
页面除支持 Vue 组件生命周期外还支持下方页面生命周期函数,当以组合式 API 使用时,在 Vue2 和 Vue3 中存在一定区别,请分别参考:Vue2 组合式 API 使用文档 和 Vue3 组合式 API 使用文档。
函数名 | 说明 | 平台差异说明 | 最低版本 |
---|---|---|---|
onInit | 监听页面初始化,其参数同 onLoad 参数,为上个页面传递的数据,参数类型为 Object(用于页面传参),触发时机早于 onLoad | 百度小程序 | 3.1.0+ |
onLoad | 监听页面加载,该钩子被调用时,响应式数据、计算属性、方法、侦听器、props、slots 已设置完成,其参数为上个页面传递的数据,参数类型为 Object(用于页面传参),参考示例。 | ||
onShow | 监听页面显示,页面每次出现在屏幕上都触发,包括从下级页面点返回露出当前页面 | ||
onReady | 监听页面初次渲染完成,此时组件已挂载完成,DOM 树($el)已可用,注意如果渲染速度快,会在页面进入动画完成前触发 | ||
onHide | 监听页面隐藏 | ||
onUnload | 监听页面卸载 | ||
onResize | 监听窗口尺寸变化 | App、微信小程序、快手小程序 | |
onPullDownRefresh | 监听用户下拉动作,一般用于下拉刷新,参考示例 | ||
onReachBottom | 页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。具体见下方注意事项 | ||
onTabItemTap | 点击 tab 时触发,参数为Object,具体见下方注意事项 | 微信小程序、QQ小程序、支付宝小程序、百度小程序、H5、App、快手小程序、京东小程序 | |
onShareAppMessage | 用户点击右上角分享 | 微信小程序、QQ小程序、支付宝小程序、抖音小程序、飞书小程序、快手小程序、京东小程序 | |
onPageScroll | 监听页面滚动,参数为Object | nvue不支持 | |
onNavigationBarButtonTap | 监听原生标题栏按钮点击事件,参数为Object | App、H5 | |
onBackPress | 监听页面返回,返回 event = {from:backbutton、 navigateBack} ,backbutton 表示来源是左上角返回按钮或 android 返回键;navigateBack表示来源是 uni.navigateBack;详见 | app、H5、支付宝小程序 | |
onNavigationBarSearchInputChanged | 监听原生标题栏搜索输入框输入内容变化事件 | App、H5 | 1.6.0 |
onNavigationBarSearchInputConfirmed | 监听原生标题栏搜索输入框搜索事件,用户点击软键盘上的“搜索”按钮时触发。 | App、H5 | 1.6.0 |
onNavigationBarSearchInputClicked | 监听原生标题栏搜索输入框点击事件(pages.json 中的 searchInput 配置 disabled 为 true 时才会触发) | App、H5 | 1.6.0 |
onShareTimeline | 监听用户点击右上角转发到朋友圈 | 微信小程序 | 2.8.1+ |
onAddToFavorites | 监听用户点击右上角收藏 | 微信小程序、QQ小程序 | 2.8.1+ |
示例代码
onLoad(options) { // options上个页面跳转过来的参数
console.log("页面加载了!", options) //执行一次
},
onShow() {
console.log("页面显示了!") //可执行多次
},
onReady() {
console.log("页面初次渲染完成!") //执行一次
},
onHide() {
console.log("页面隐藏了!") //可执行多次
},
七、下拉刷新
1.onPullDownRefresh
在 js 中定义 onPullDownRefresh 处理函数(和onLoad等生命周期函数同级),监听该页面用户下拉刷新事件。
- 需要在
pages.json
里,找到的当前页面的pages节点,并在style
选项中开启enablePullDownRefresh
。 - 当处理完数据刷新后,
uni.stopPullDownRefresh
可以停止当前页面的下拉刷新。
#uni.startPullDownRefresh(OBJECT)
开始下拉刷新,调用后触发下拉刷新动画,效果与用户手动下拉刷新一致。
OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
success | Function | 否 | 接口调用成功的回调 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明
参数 | 类型 | 说明 |
---|---|---|
errMsg | String | 接口调用结果 |
使用示例
<view v-for="item in list">{{item}}</view>
<button @click="pulldown">手动点击</button>
onPullDownRefresh() {
console.log("触发了下拉刷新!");
setTimeout(() => {
this.list = [
'前端', 'java', '测试', '大数据', 'UI'
]
uni.stopPullDownRefresh();
}, 2000)
},
methods: {
pulldown() {//点击按钮下拉刷新
uni.startPullDownRefresh();
}
}
#uni.stopPullDownRefresh()
停止当前页面下拉刷新。
示例
pages.json
{
"pages": [
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app",
"enablePullDownRefresh": true
}
}
],
"globalStyle": {
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#0faeff",
"backgroundColor": "#fbf9fe"
}
}
index.vue
// 仅做示例,实际开发中延时根据需求来使用。
export default {
data() {
return {
text: 'uni-app'
}
},
onLoad: function (options) {
setTimeout(function () {
console.log('start pulldown');
}, 1000);
uni.startPullDownRefresh();
},
onPullDownRefresh() {
console.log('refresh');
setTimeout(function () {
uni.stopPullDownRefresh();
}, 1000);
}
}
注意
- 支付宝小程序
startPullDownRefresh
在开发者工具里会提示暂未开放,请勿使用
- 支付宝小程序
startPullDownRefresh
请使用真机调试(非真机预览) - 后续支付宝小程序开发工具更新可能会有所修改
#FAQ
Q:如何暂时禁用掉下拉刷新,待需要的时候再重新开启? A:App
平台下可以处理此类场景,详细参考:uni-app 中实现动态禁用/开启下拉刷新
Q:自定义title如何让下拉刷新在title之下 A:App和H5端使用circle方式的下拉刷新,设offset在title高度之下。hello uni-app的模板-导航栏中有示例。小程序端无法实现,除非放弃原生下拉刷新,自己模拟下拉刷新,插件市场有类似插件,但性能不如原生下拉刷新。
Q:如何自定义下拉刷新样式 A:小程序端的原生下拉刷新样式是固定的;App端原生的下拉刷新有2种样式可选择,下拉漏出雪花和下拉circle圈。如果使用nvue,可以使用refresh组件自定义下拉刷新,都是原生渲染。如果想使用scroll-view在前端实现自定义下拉刷新,需要注意列表不可太长和太复杂,否则会有性能问题。插件市场搜索下拉刷新有示例。
2.onReachBottom
可在pages.json里定义具体页面底部的触发距离onReachBottomDistance,
比如设为50,那么滚动页面到距离底部50px时,就会触发onReachBottom事件。
如使用scroll-view导致页面没有滚动,则触底事件不会被触发。scroll-view滚动到底部的事件请参考scroll-view的文档。
示例代码:
Page.json
"onReachBottomDistance": 10, 配置下拉触底的距离
onReachBottom() {
console.log("页面进行触底")
},
八、网络请求
发起网络请求。
在各个小程序平台运行时,网络相关的 API 在使用前需要配置域名白名单。
OBJECT 参数说明
参数名 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
url | String | 是 | 开发者服务器接口地址 | ||
data | Object/String/ArrayBuffer | 否 | 请求的参数 | App 3.3.7 以下不支持 ArrayBuffer 类型 | |
header | Object | 否 | 设置请求的 header,header 中不能设置 Referer | App、H5端会自动带上cookie,且H5端不可手动修改 | |
method | String | 否 | GET | 有效值详见下方说明 | |
timeout | Number | 否 | 60000 | 超时时间,单位 ms | H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序 |
dataType | String | 否 | json | 如果设为 json,会对返回的数据进行一次 JSON.parse,非 json 不会进行 JSON.parse | |
responseType | String | 否 | text | 设置响应的数据类型。合法值:text、arraybuffer | 支付宝小程序不支持 |
sslVerify | Boolean | 否 | true | 验证 ssl 证书 | 仅App安卓端支持(HBuilderX 2.3.3+),不支持离线打包 |
withCredentials | Boolean | 否 | false | 跨域请求时是否携带凭证(cookies) | 仅H5支持(HBuilderX 2.6.15+) |
firstIpv4 | Boolean | 否 | false | DNS解析时优先使用ipv4 | 仅 App-Android 支持 (HBuilderX 2.8.0+) |
enableHttp2 | Boolean | 否 | false | 开启 http2 | 微信小程序 |
enableQuic | Boolean | 否 | false | 开启 quic | 微信小程序 |
enableCache | Boolean | 否 | false | 开启 cache | 微信小程序、抖音小程序 2.31.0+ |
enableHttpDNS | Boolean | 否 | false | 是否开启 HttpDNS 服务。如开启,需要同时填入 httpDNSServiceId 。 HttpDNS 用法详见 移动解析HttpDNS | 微信小程序 |
httpDNSServiceId | String | 否 | HttpDNS 服务商 Id。 HttpDNS 用法详见 移动解析HttpDNS | 微信小程序 | |
enableChunked | Boolean | 否 | false | 开启 transfer-encoding chunked | 微信小程序 |
forceCellularNetwork | Boolean | 否 | false | wifi下使用移动网络发送请求 | 微信小程序 |
enableCookie | Boolean | 否 | false | 开启后可在headers中编辑cookie | 支付宝小程序 10.2.33+ |
cloudCache | Object/Boolean | 否 | false | 是否开启云加速(详见云加速服务) | 百度小程序 3.310.11+ |
defer | Boolean | 否 | false | 控制当前请求是否延时至首屏内容渲染后发送 | 百度小程序 3.310.11+ |
success | Function | 否 | 收到开发者服务器成功返回的回调函数 | ||
fail | Function | 否 | 接口调用失败的回调函数 | ||
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
method 有效值
注意:method有效值必须大写,每个平台支持的method有效值不同,详细见下表。
method | App | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 抖音小程序、飞书小程序 | 快手小程序 | 京东小程序 |
---|---|---|---|---|---|---|---|---|
GET | √ | √ | √ | √ | √ | √ | √ | √ |
POST | √ | √ | √ | √ | √ | √ | √ | √ |
PUT | √ | √ | √ | x | √ | √ | x | x |
DELETE | √ | √ | √ | x | √ | x | x | x |
CONNECT | x | √ | √ | x | x | x | x | x |
HEAD | √ | √ | √ | x | √ | x | x | x |
OPTIONS | √ | √ | √ | x | √ | x | x | x |
TRACE | x | √ | √ | x | x | x | x | x |
success 返回参数说明
参数 | 类型 | 说明 |
---|---|---|
data | Object/String/ArrayBuffer | 开发者服务器返回的数据 |
statusCode | Number | 开发者服务器返回的 HTTP 状态码 |
header | Object | 开发者服务器返回的 HTTP Response Header |
cookies | Array.<string> | 开发者服务器返回的 cookies,格式为字符串数组 |
data 数据说明
最终发送给服务器的数据是 String 类型,如果传入的 data 不是 String 类型,会被转换成 String。转换规则如下:
- 对于
GET
方法,会将数据转换为 query string。例如{ name: 'name', age: 18 }
转换后的结果是name=name&age=18
。 - 对于
POST
方法且header['content-type']
为application/json
的数据,会进行 JSON 序列化。 - 对于
POST
方法且header['content-type']
为application/x-www-form-urlencoded
的数据,会将数据转换为 query string。
示例
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';
}
});
返回值
如果希望返回一个 requestTask
对象,需要至少传入 success / fail / complete 参数中的一个。例如:
var requestTask = uni.request({
url: 'https://www.example.com/request', //仅为示例,并非真实接口地址。
complete: ()=> {}
});
requestTask.abort();
如果没有传入 success / fail / complete 参数,则会返回封装后的 Promise 对象:Promise 封装
通过 requestTask
,可中断请求任务。
requestTask 对象的方法列表
方法 | 参数 | 说明 |
---|---|---|
abort | 中断请求任务 | |
offHeadersReceived | 取消监听 HTTP Response Header 事件,仅微信小程序平台 支持,文档详情 | |
onHeadersReceived | 监听 HTTP Response Header 事件。会比请求完成事件更早,仅微信小程序平台 支持,文档详情 |
示例
const requestTask = uni.request({
url: 'https://www.example.com/request', //仅为示例,并非真实接口地址。
data: {
name: 'name',
age: 18
},
success: function(res) {
console.log(res.data);
}
});
// 中断请求任务
requestTask.abort();
1.发送get请求
示例代码
get() {
uni.request({
url: "http://localhost:8082/api/getlunbo",
success(res) {
console.log(res)
}
})
}
九、数据缓存
1.uni.setStorage(OBJECT)
将数据存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个异步接口。
OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
key | String | 是 | 本地缓存中的指定的 key |
data | Any | 是 | 需要存储的内容,只支持原生类型、及能够通过 JSON.stringify 序列化的对象 |
success | Function | 否 | 接口调用成功的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例
uni.setStorage({
key: 'storage_key',
data: 'hello', //任意类型
success: function () {
console.log('success');
}
});
复制代码
注意
uni-
、uni_
、dcloud-
、dcloud_
为前缀的key,为系统保留关键前缀。如uni_deviceId
、uni_id_token
,请开发者为key命名时避开这些前缀。
2.#uni.setStorageSync(KEY,DATA)
将 data 存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容,这是一个同步接口。
参数说明
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
key | String | 是 | 本地缓存中的指定的 key |
data | Any | 是 | 需要存储的内容,只支持原生类型、及能够通过 JSON.stringify 序列化的对象 |
try {
uni.setStorageSync('storage_key', 'hello');
} catch (e) {
// error
}
复制代码
3.#uni.getStorage(OBJECT)
从本地缓存中异步获取指定 key 对应的内容。
OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
key | String | 是 | 本地缓存中的指定的 key |
success | Function | 是 | 接口调用的回调函数,res = {data: key对应的内容} |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明
参数 | 类型 | 说明 |
---|---|---|
data | Any | key 对应的内容 |
示例
uni.getStorage({
key: 'storage_key',
success: function (res) {
console.log(res.data);
}
});
复制代码
4.#uni.getStorageSync(KEY)
从本地缓存中同步获取指定 key 对应的内容。
参数说明
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
key | String | 是 | 本地缓存中的指定的 key |
示例
try {
const value = uni.getStorageSync('storage_key');
if (value) {
console.log(value);
}
} catch (e) {
// error
}
5.#uni.removeStorage(OBJECT)
从本地缓存中异步移除指定 key。
OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
key | String | 是 | 本地缓存中的指定的 key |
success | Function | 是 | 接口调用的回调函数 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
示例
uni.removeStorage({
key: 'storage_key',
success: function (res) {
console.log('success');
}
});
复制代码
6.#uni.removeStorageSync(KEY)
从本地缓存中同步移除指定 key。
参数说明
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
key | String | 是 | 本地缓存中的指定的 key |
示例
try {
uni.removeStorageSync('storage_key');
} catch (e) {
// error
}
十、上传预览
1.上传图片
uni.chooseImage(OBJECT)
从本地相册选择图片或使用相机拍照。
App端如需要更丰富的相机拍照API(如直接调用前置摄像头),参考plus.camera
微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
count | Number | 否 | 最多可以选择的图片张数,默认9 | 见下方说明 |
sizeType | Array | 否 | original 原图,compressed 压缩图,默认二者都有 | App、微信小程序、支付宝小程序、百度小程序 |
extension | Array | 否 | 根据文件拓展名过滤,每一项都不能是空字符串。默认不过滤。 | H5(HBuilder X2.9.9+) |
sourceType | Array | 否 | album 从相册选图,camera 使用相机,默认二者都有。如需直接开相机或直接选相册,请只使用一个选项 | |
crop | Object | 否 | 图像裁剪参数,设置后 sizeType 失效 | App 3.1.19+ |
success | Function | 是 | 成功则返回图片的本地文件路径列表 tempFilePaths | |
fail | Function | 否 | 接口调用失败的回调函数 | 小程序、App |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
crop 参数说明
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
quality | Number | 否 | 取值范围为1-100,数值越小,质量越低(仅对jpg格式有效)。默认值为80。 | |
width | Number | 是 | 裁剪的宽度,单位为px,用于计算裁剪宽高比。 | |
height | Number | 是 | 裁剪的高度,单位为px,用于计算裁剪宽高比。 | |
resize | Boolean | 否 | 是否将width和height作为裁剪保存图片真实的像素值。默认值为true。注:设置为false时在裁剪编辑界面显示图片的像素值,设置为true时不显示 |
Tips
- count 值在 H5 平台的表现,基于浏览器本身的规范。目前测试的结果来看,只能限制单选/多选,并不能限制数量。并且,在实际的手机浏览器很少有能够支持多选的。
- sourceType 值在 H5 平台根据浏览器的不同而表现不同,一般不可限制仅使用相册,部分浏览器也无法限制是否使用相机。
- 可以通过用户授权API来判断用户是否给应用授予相册或摄像头的访问权限https://uniapp.dcloud.io/api/other/authorize
- App端如需选择非媒体文件,可在插件市场搜索文件选择,其中Android端可以使用Native.js,无需原生插件,而iOS端需要原生插件。
- 选择照片大多为了上传,uni ui封装了更完善的uni-file-picker组件,文件选择、上传到uniCloud的免费存储和cdn中,一站式集成。强烈推荐使用。
- App上有时会遇到图片旋转90度问题,插件市场有解决方案:图片旋转
- 微信小程序在2023年10月17日之后,使用API需要配置隐私协议
- 在部分低端机如红米上拍照闪退,拍照调用的是系统相机,当系统内存不足,rom为了给相机activity分配内存而把app的主activity回收了。遇到此问题建议使用nvue页面并内嵌的自定义相机的原生或uts插件。相关分析报告详见
注:文件的临时路径,在应用本次启动期间可以正常使用,如需持久保存,需在主动调用 uni.saveFile,在应用下次启动时才能访问得到。
success 返回参数说明
参数 | 类型 | 说明 |
---|---|---|
tempFilePaths | Array | 图片的本地文件路径列表 |
tempFiles | Array、Array | 图片的本地文件列表,每一项是一个 File 对象 |
File 对象结构如下
参数 | 类型 | 说明 |
---|---|---|
path | String | 本地文件路径 |
size | Number | 本地文件大小,单位:B |
name | String | 包含扩展名的文件名称,仅H5支持 |
type | String | 文件类型,仅H5支持 |
示例
uni.chooseImage({
count: 6, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function (res) {
console.log(JSON.stringify(res.tempFilePaths));
}
});
2.预览图片
uni.previewImage(OBJECT)
预览图片。
OBJECT 参数说明
参数名 | 类型 | 必填 | 说明 | 平台差异说明 |
---|---|---|---|---|
current | String/Number | 详见下方说明 | 详见下方说明 | |
showmenu | Boolean | 否 | 是否显示长按菜单,默认值为 true | 微信小程序2.13.0 |
urls | Array | 是 | 需要预览的图片链接列表 | |
indicator | String | 否 | 图片指示器样式,可取值:“default” - 底部圆点指示器; “number” - 顶部数字指示器; “none” - 不显示指示器。 | App |
loop | Boolean | 否 | 是否可循环预览,默认值为 false | App |
longPressActions | Object | 否 | 长按图片显示操作菜单,如不填默认为保存相册 | App 1.9.5+ |
success | Function | 否 | 接口调用成功的回调函数 | |
fail | Function | 否 | 接口调用失败的回调函数 | |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
current 参数说明
1.9.5+ 支持传图片在 urls 中的索引值
current 为当前显示图片的链接/索引值,不填或填写的值无效则为 urls 的第一张。App平台在 1.9.5至1.9.8之间,current为必填。不填会报错
注意,当 urls 中有重复的图片链接时:
- 传链接,预览结果始终显示该链接在 urls 中第一次出现的位置。
- 传索引值,在微信/百度/抖音小程序平台,会过滤掉传入的 urls 中该索引值之前与其对应图片链接重复的值。其它平台会保留原始的 urls 不会做去重处理。
举例说明:
一组图片 [A, B1, C, B2, D]
,其中 B1 与 B2 的图片链接是一样的。
- 传 B2 的链接,预览的结果是 B1,前一张是 A,下一张是 C。
- 传 B2 的索引值 3,预览的结果是 B2,前一张是 C,下一张是 D。此时在微信/百度/抖音小程序平台,最终传入的 urls 是
[A, C, B2, D]
,过滤掉了与 B2 重复的 B1。
longPressActions 参数说明
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
itemList | Array | 是 | 按钮的文字数组 |
itemColor | String | 否 | 按钮的文字颜色,字符串格式,默认为"#000000" |
success | Function | 否 | 接口调用成功的回调函数,详见返回参数说明 |
fail | Function | 否 | 接口调用失败的回调函数 |
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
success 返回参数说明
参数 | 类型 | 说明 |
---|---|---|
index | Number | 用户长按图片的索引值 |
tapIndex | Number | 用户点击按钮列表的索引值 |
示例
// 从相册选择6张图
uni.chooseImage({
count: 6,
sizeType: ['original', 'compressed'],
sourceType: ['album'],
success: function(res) {
// 预览图片
uni.previewImage({
urls: res.tempFilePaths,
longPressActions: {
itemList: ['发送给朋友', '保存图片', '收藏'],
success: function(data) {
console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
},
fail: function(err) {
console.log(err.errMsg);
}
}
});
}
});
TIPS
- 在非H5端,previewImage是原生实现的,界面自定义灵活度较低。
- 插件市场有前端实现的previewImage,性能低于原生实现,但界面可随意定义;插件市场也有适于App端的previewImage原生插件,提供了更多功能。
测试代码
<template>
<view>
<button type="default" @click="uploadimage">上传图片</button>
<image v-for=" item in ImageArr" :src="item" @click="previewImage(item)"></image>
</view>
</template>
<script>
export default {
data() {
return {
ImageArr: []
}
},
methods: {
//上传图片
uploadimage() {
uni.chooseImage({
count: 6, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: res => {
console.log(JSON.stringify(res.tempFilePaths));
this.ImageArr = res.tempFilePaths;
}
});
},
//预览图片
previewImage(current) {
uni.previewImage({
current: current, //图片路径
urls: this.ImageArr, //图片数组
loop: true, //是否可以循环预览 无效
indicator: Number // 图片指示器样式 无效
})
}
}
}
</script>
<style>
</style>
十一、条件注释/跨端兼容
条件编译处理多端差异
#为什么选择条件编译处理跨端兼容
uni-app 已将常用的组件、API封装到框架中,开发者按照 uni-app 规范开发即可保证多平台兼容,大部分业务均可直接满足。
但每个平台有自己的一些特性,因此会存在一些无法跨平台的情况。
- 大量写 if else,会造成代码执行性能低下和管理混乱。
- 编译到不同的工程后二次修改,会让后续升级变的很麻烦。
- 为每个平台重写,明明主业务逻辑又一样
在 C 语言中,通过 #ifdef
、#ifndef
的方式,为 Windows、Mac 等不同 OS 编译不同的代码。
uni-app
团队参考这个思路,为 uni-app
提供了条件编译手段,在一个工程里优雅的完成了平台个性化实现。
#条件编译
条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。
#使用方法
以 #ifdef
或 #ifndef
加 %PLATFORM%
开头,以 #endif
结尾。
#ifdef
:if defined 仅在某平台存在#ifndef
:if not defined 除了某平台均存在%PLATFORM%
:平台名称
条件编译写法 | 说明 |
---|---|
#ifdef APP-PLUS 需条件编译的代码 #endif | 仅出现在 App 平台下的代码 |
#ifndef H5 需条件编译的代码 #endif | 除了 H5 平台,其它平台均存在的代码(注意if后面有个n) |
#ifdef H5 || MP-WEIXIN 需条件编译的代码 #endif | 在 H5 平台或微信小程序平台存在的代码(这里只有||,不可能出现&&,因为没有交集) |
%PLATFORM%
可取值:
值 | 生效条件 | 版本支持 |
---|---|---|
VUE3 | uni-app js引擎版用于区分vue2和3,详情 | HBuilderX 3.2.0+ |
VUE2 | uni-app js引擎版用于区分vue2和3,详情 | |
UNI-APP-X | 用于区分是否是uni-app x项目 详情 | HBuilderX 3.9.0+ |
uniVersion | 用于区分编译器的版本 详情 | HBuilderX 3.9.0+ |
APP | App | |
APP-PLUS | uni-app js引擎版编译为App时 | |
APP-PLUS-NVUE或APP-NVUE | App nvue 页面 | |
APP-ANDROID | App Android 平台 详情 | |
APP-IOS | App iOS 平台 详情 | |
H5 | H5(推荐使用 WEB ) | |
WEB | web(同H5 ) | HBuilderX 3.6.3+ |
MP-WEIXIN | 微信小程序 | |
MP-ALIPAY | 支付宝小程序 | |
MP-BAIDU | 百度小程序 | |
MP-TOUTIAO | 抖音小程序 | |
MP-LARK | 飞书小程序 | |
MP-QQ | QQ小程序 | |
MP-KUAISHOU | 快手小程序 | |
MP-JD | 京东小程序 | |
MP-360 | 360小程序 | |
MP | 微信小程序/支付宝小程序/百度小程序/抖音小程序/飞书小程序/QQ小程序/360小程序 | |
QUICKAPP-WEBVIEW | 快应用通用(包含联盟、华为) | |
QUICKAPP-WEBVIEW-UNION | 快应用联盟 | |
QUICKAPP-WEBVIEW-HUAWEI | 快应用华为 |
支持的文件:
- .vue/.nvue/.uvue
- .js/.uts
- .css
- pages.json
- 各预编译语言文件,如:.scss、.less、.stylus、.ts、.pug
1.组件中条件编译
<!-- #ifdef H5 -->
<view>我希望只在H5中看见</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<view>我希望只在小程序中看见</view>
<!-- #endif -->
2.API条件编译
onLoad() {
// #ifdef H5
console.log("在H5中打印");
//#endif
// #ifdef MP-WEIXIN
console.log("在小程序中打印");
//#endif
},
/* h5中的样式 */
/* #ifdef H5 */
view{
color: hotpink;
}
/* #endif */
/* 微信小程序中的样式 */
/* #ifdef MP-WEIXIN */
view{
color: #0000FF;
}
/* #endif */
十二、导航跳转
1.navigator进行跳转
页面跳转。
该组件类似HTML中的<a>
组件,但只能跳转本地页面。目标页面必须在pages.json中注册。
除了组件方式,API方式也可以实现页面跳转,另见:https://uniapp.dcloud.io/api/router?id=navigateto
属性说明
属性名 | 类型 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|
url | String | 应用内的跳转链接,值为相对路径或绝对路径,如:“…/first/first”,“/pages/first/first”,注意不能加 .vue 后缀 | ||
open-type | String | navigate | 跳转方式 | |
delta | Number | 当 open-type 为 ‘navigateBack’ 时有效,表示回退的层数 | ||
animation-type | String | pop-in/out | 当 open-type 为 navigate、navigateBack 时有效,窗口的显示/关闭动画效果,详见:窗口动画 | App |
animation-duration | Number | 300 | 当 open-type 为 navigate、navigateBack 时有效,窗口显示/关闭动画的持续时间。 | App |
render-link | boolean | true | 是否给 navigator 组件加一层 a 标签控制 ssr 渲染 | web3.7.6+、App-vue3.7.6+ |
hover-class | String | navigator-hover | 指定点击时的样式类,当hover-class="none"时,没有点击态效果 | |
hover-stop-propagation | Boolean | false | 指定是否阻止本节点的祖先节点出现点击态 | 微信小程序 |
hover-start-time | Number | 50 | 按住后多久出现点击态,单位毫秒 | |
hover-stay-time | Number | 600 | 手指松开后点击态保留时间,单位毫秒 | |
target | String | self | 在哪个小程序目标上发生跳转,默认当前小程序,值域self/miniProgram | 微信2.0.7+、百度2.5.2+、QQ |
open-type 有效值
值 | 说明 | 平台差异说明 |
---|---|---|
navigate | 对应 uni.navigateTo 的功能 | |
redirect | 对应 uni.redirectTo 的功能 | |
switchTab | 对应 uni.switchTab 的功能 | |
reLaunch | 对应 uni.reLaunch 的功能 | 抖音小程序与飞书小程序不支持 |
navigateBack | 对应 uni.navigateBack 的功能 | |
exit | 退出小程序,target="miniProgram"时生效 | 微信2.1.0+、百度2.5.2+、QQ1.4.7+ |
这些细节可在页面路由API文档查阅。
注意
- 跳转tabbar页面,必须设置open-type=“switchTab”
- navigator-hover 默认为 {background-color: rgba(0, 0, 0, 0.1); opacity: 0.7;},
<navigator>
的子节点背景色应为透明色。 - navigator-
open-type
属性 如果使用对应的值,则对应值的功能会高于对应跳转路径。 - app-nvue 平台只有纯nvue项目(render为native)才支持
<navigator>
。非render为native的情况下,nvue暂不支持navigator组件,请使用API跳转。 - app下退出应用,Android平台可以使用plus.runtime.quit。iOS没有退出应用的概念。
- uLink组件是navigator组件的增强版,样式上自带下划线,功能上支持打开在线网页、其他App的schema、mailto发邮件、tel打电话。
- Vue3 项目因 SSR 需要,H5 端会在外层嵌套 a 标签
跳转到普通页面
<navigator url="/pages/detail/detail?id=80&age=19">跳转至详情页</navigator>
跳转到tabbar页面
<navigator url="/pages/message/message" open-type="switchTab">跳转至信息页</navigator>
<navigator url="/pages/detail/detail" open-type="redirect">跳转至详情页(没有返回)当前页面关闭后跳转</navigator>
2.利用编程试导航进行跳转
uni.navigateTo(OBJECT)
保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack
可以返回到原页面。
OBJECT参数说明
参数 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
url | String | 是 | 需要跳转的应用内非 tabBar 的页面的路径 , 路径后可以带参数。参数与路径之间使用?分隔,参数键与参数值用=相连,不同参数用&分隔;如 ‘path?key=value&key2=value2’,path为下一个页面的路径,下一个页面的onLoad函数可得到传递的参数 | ||
animationType | String | 否 | pop-in | 窗口显示的动画效果,详见:窗口动画 | App |
animationDuration | Number | 否 | 300 | 窗口动画持续时间,单位为 ms | App |
events | Object | 否 | 页面间通信接口,用于监听被打开页面发送到当前页面的数据。2.8.9+ 开始支持。 | ||
success | Function | 否 | 接口调用成功的回调函数 | ||
fail | Function | 否 | 接口调用失败的回调函数 | ||
complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |
object.success 回调函数
参数
Object res
属性 | 类型 | 说明 |
---|---|---|
eventChannel | EventChannel | 和被打开页面进行通信 |
示例
//在起始页面跳转到test.vue页面并传递参数
uni.navigateTo({
url: 'test?id=1&name=uniapp'
});
复制代码
// 在test.vue页面接受参数
export default {
onLoad: function (option) { //option为object类型,会序列化上个页面传递的参数
console.log(option.id); //打印出上个页面传递的参数。
console.log(option.name); //打印出上个页面传递的参数。
}
}
// 在起始页面跳转到test.vue页面,并监听test.vue发送过来的事件数据
uni.navigateTo({
url: '/pages/test?id=1',
events: {
// 为指定事件添加一个监听器,获取被打开页面传送到当前页面的数据
acceptDataFromOpenedPage: function(data) {
console.log(data)
},
someEvent: function(data) {
console.log(data)
}
...
},
success: function(res) {
// 通过eventChannel向被打开页面传送数据
res.eventChannel.emit('acceptDataFromOpenerPage', { data: 'data from starter page' })
}
})
// 在test.vue页面,向起始页通过事件传递数据
onLoad: function(option) {
const eventChannel = this.getOpenerEventChannel();
eventChannel.emit('acceptDataFromOpenedPage', {data: 'data from test page'});
eventChannel.emit('someEvent', {data: 'data from test page for someEvent'});
// 监听acceptDataFromOpenerPage事件,获取上一页面通过eventChannel传送到当前页面的数据
eventChannel.on('acceptDataFromOpenerPage', function(data) {
console.log(data)
})
}
复制代码
vue3 script setup
语法糖中调用 getOpenerEventChannel
示例:
<script setup>
import {
onMounted,
getCurrentInstance
} from 'vue';
onMounted(() => {
const instance = getCurrentInstance().proxy
const eventChannel = instance.getOpenerEventChannel();
eventChannel.emit('acceptDataFromOpenedPage', {
data: 'data from test page'
});
eventChannel.emit('someEvent', {
data: 'data from test page for someEvent'
});
eventChannel.on('acceptDataFromOpenerPage', function(data) {
console.log('acceptDataFromOpenerPage', data)
})
})
</script>
复制代码
url有长度限制,太长的字符串会传递失败,可改用窗体通信、全局变量,另外参数中出现空格等特殊字符时需要对参数进行编码,如下为使用encodeURIComponent
对参数进行编码的示例。
<navigator :url="'/pages/test/test?item='+ encodeURIComponent(JSON.stringify(item))"></navigator>
复制代码
// 在test.vue页面接受参数
onLoad: function (option) {
const item = JSON.parse(decodeURIComponent(option.item));
}
复制代码
注意:
- 页面跳转路径有层级限制,不能无限制跳转新页面
- 跳转到 tabBar 页面只能使用 switchTab 跳转
- 路由API的目标页面必须是在pages.json里注册的vue页面。如果想打开web url,在App平台可以使用 plus.runtime.openURL或web-view组件;H5平台使用 window.open;小程序平台使用web-view组件(url需在小程序的联网白名单中)。在hello uni-app中有个组件ulink.vue已对多端进行封装,可参考。
<button @click="goDetail">跳转之详情页</button>
<button @click="goMessage">跳转至信息页</button>
<button type="primary" @click="redirectDetail()">跳转到详情页并关闭当前页面</button>
<button type="primary" @click="addToCar">加入购物车</button>
goDetail () {
uni.navigateTo({ //跳转到非tabber
url: '/pages/detail/detail?id=80&age=19'
})
},
goMessage () {
uni.switchTab({ //跳转到tabber,关闭非tabber页面
url: '/pages/message/message'
})
},
redirectDetail () {
uni.redirectTo({ //跳转到详情页并关闭当前页面
url: '/pages/detail/detail'
});
},
addToCar () {
uni.$emit('updateCart',{
id: 10,
name: '贸易'
})
}
3.导航跳转传递参数
组件跳转传递参数
<navigator url="/pages/detail/detail?id=80&age=19">跳转至详情页</navigator>
组件跳转接收参数
onLoad(options){
console.log(options)
}
编程跳转传参
uni.navigateTo({ //跳转到非tabber
url: '/pages/detail/detail?id=80&age=19'
})
十三、组件的创建
1.组件的生命周期函数
组件注册
components
<template>
<view>
这是test组件
</view>
</template>
<script>
export default {
name: "test",
data() {
return {
};
}
}
</script>
<style>
</style>
使用这个组件
<template>
<view>
<test></test>
</view>
</template>
<script>
import test from "../../components/test.vue" //导入组件
export default {
data() {
return {
}
},
methods: {
},
components: { //注册组件
test
}
}
</script>
组件生命周期
uni-app
组件支持的生命周期,与vue标准组件的生命周期相同。这里没有页面级的onLoad等生命周期:
函数名 | 说明 | 平台差异说明 | 最低版本 |
---|---|---|---|
beforeCreate | 在实例初始化之前被调用。详见 | ||
created | 在实例创建完成后被立即调用。详见 | ||
beforeMount | 在挂载开始之前被调用。详见 | ||
mounted | 挂载到实例上去之后调用。详见 注意:此处并不能确定子组件被全部挂载,如果需要子组件完全挂载之后在执行操作可以使用$nextTick Vue官方文档 | ||
beforeUpdate | 数据更新时调用,发生在虚拟 DOM 打补丁之前。详见 | 仅H5平台支持 | |
updated | 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。详见 | 仅H5平台支持 | |
beforeDestroy | 实例销毁之前调用。在这一步,实例仍然完全可用。详见 | ||
destroyed | Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁 |
beforeCreate() { //初始化未完成
console.log("实例已经开始初始化了")
console.log(this.num)
},
created() { //初始化完成
console.log("created")
console.log(this.num)
},
beforeMount() { //在挂载开始之前被调用
console.log("beforemount")
},
mounted() { //挂载到实例上去之后调用
console.log('mounted')
}
十四、组件的通讯
1.父组件给子组件传值
通过props来接受外界传递到组件内部的值
<test v-if="flag" :title="title"></test>
<template>
<view id="myView">
这是test组件{{num}}
这是父组件传递过来的数据{{title}}
</view>
</template>
<script>
export default {
data() {
return {
num: 3,
intId: null
};
},
props: ['title'] // 接受父组件传值
}
</script>
2.子组件给父组件传值
通过$emit触发事件进行传递参数
子组件
<template>
<view id="myView">
这是test组件{{num}}
这是父组件传递过来的数据{{title}}
<button @click="sendNum">给父组件传值</button>
</view>
</template>
<script>
export default {
data() {
return {
num: 3,
intId: null
};
},
props: ['title'],
methods: {
sendNum() {
console.log('给父亲传值')
this.$emit('myEven',this.num) //在这里传值 myEven 自定义事件名称
}
}
}
</script>
父组件
<test v-if="flag" :title="title" @myEven="getNum"></test>
<script>
export default {
data() {
return {
num:0
}
},
methods: {
getNum (num) {
console.log(num)
this.num = num
},
}
}
</script>
3.兄弟组件通讯
a组件
<template>
<view>
这是a组件:<button @click="addNum">修改b组件的数据</button>
</view>
</template>
<script>
export default {
data() {
return {
};
},
methods: {
addNum () {
uni.$emit('updateNum',10) //触发b组件自定义的全局事件并传值
}
}
}
</script>
b组件
<template>
<view>
这是b组件的数据:{{num}}
</view>
</template>
<script>
export default {
data() {
return {
num: 0
};
},
created(){
uni.$on('updateNum',num=>{ //注册一个全局事件,等待a组件调用
this.num+=num
})
}
}
</script>