uni-app 使用笔记
1.前言
也不知道是我水平菜还是文档太烂,这个框架使用的过程中踩了无数的坑,屡次想砸键盘,最后贫穷让我平复了心情。为了纪念这段操蛋的日子,我决定把这些坑都记录下来。
2.数据请求
在实际的项目中,数据请求需要配合一些UI效果,例如请求数据时展示'loading'效果,数据回来后又要取消这种'loading'效果,既然每次都要使用,干脆进行封装。
在utils目录下新建ajax.js文件,写入
export default(params)=>{
uni.showLoading({
title:"加载中",
});
return new Promise((resolve,reject)=>{
wx.request({
...params, //es6语法
success(res){
//请求成功
resolve(res.data);
},
fail(err){
//请求失败
reject(err);
},
complete(){
//请求无论成功还是失败都会执行
uni.hideLoading();
}
});
});
}
用法:
- 1.在main.js文件中,将其挂载到原型链中
//引入ajax模块
import ajax from './utils/ajax.js'
//挂载到原型链中
Vue.prototype.$ajax = ajax
- 2.在页面上配合async和await使用
async getData(){
try{
const result = await this.$ajax({
url:'/api/ensample',
})
}catch(e){
console.log(e)
}
},
3.下拉刷新
项目需求:头部区域保持固定,主体区域存放内容,下拉刷新,上拉加载。
候选实现方式:
(1)使用页面级下拉刷新
(2)使用区域滚动view-scroll组件
分析:view-scroll不合适这种分页场景,只适合一次性加载数据展示。
下面是使用页面级下拉刷新的注意事项:
- 1.要在哪个页面中使用下拉刷新,需要在page.json中进行配置 "enablePullDownRefresh" 为 true
{
"path": "pages/device-management/device-management",
"style": {
"navigationBarTitleText": "设 备 管 理",
"enablePullDownRefresh":true
}
},
- 2.配置生命周期,为下拉刷新的手势设置回调。要注意的是,除了设置回调函数请求数据,页面会有一个 "正在刷新" 的UI效果,这个效果需要在特定时机调用 uni.stopPullDownRefresh() 取消掉这个UI效果
onPullDownRefresh(){
//判断当前是否属于刷新状态,避免重复执行
if(this.is_refresh) return
//模拟发送请求
this.is_refresh = true
console.log('发送请求')
setTimeout(()=>{
//数据回来后取消刷新的UI效果
uni.stopPullDownRefresh()
//更新刷新状态
this.is_refresh = false
},1000)
},
4.上拉加载更多
项目需求:头部区域保持固定,主体区域存放内容,下拉刷新,上拉加载。
下面是使用页面级上拉加载的注意事项:
- 1.页面上拉到底是有一个临界值的,默认情况下这个值是50px,一旦滚动条与页面底部的距离超过这个值,就触发生命周期,这个值在page.json中进行配置
{
"path": "pages/device-management/device-management",
"style": {
"navigationBarTitleText": "设 备 管 理",
"onReachBottomDistance":50,//onReachBottomDistance单位只支持px
}
},
- 2.设置生命周期 onReachBottom。在生命周期中修改页码,发送新的请求,到了最后一页提示没有更多数据。
//上拉加载
onReachBottom(){
//判断当前是否属于加载状态,避免重复执行
if(this.is_loading) return
//页码增加
this.page_number++
//判断是否已经到最后一页
if(this.page_number >= this.page_total){
uni.showToast({
title:"已经是最后一页",
icon:"none"
})
}
//请求数据
},
5.扫码
问题:在小程序端和app端可以直接调用扫码api,但是在H5端,因为浏览器本身没有统一的扫码接口,导致这个扫码api无法使用。
解决办法:要想要H5的网页支持扫码功能,需要运行环境的支持,在uniapp中使用5+app的plus对象,可以帮助H5页面调用扫码功能。
解决思路:使用条件编译,如果是H5页面,则使用uniapp提供的全局plus对象来完成扫码功能,非H5环境直接调用uni扫码接口
步骤一:条件编译
scanCode() {
//H5统一跳转到H5扫码页面进行扫描码
// #ifdef H5
uni.navigateTo({
url: '/pages/h5-scan/h5-scan',
success(res) {
console.log('跳转成功')
},
fail(err) {
console.log('跳转失败')
}
}) return
// #endif
//纯app扫码
var that = this
//调用扫描接口
uni.scanCode({
//扫描完成
complete() {
console.log('complete')
},
//扫描成功
success(res) {
//保存扫码结果
that.qrcode = res.result console.log(res.result) //res.result 为二维码对应的字符串
},
//取消扫描
fail() {
console.log('取消扫码')
}
})
}
步骤二:一进入页面立即调用扫码功能
//定义扫码方法
methods: {
//创建扫码实例并开启扫描
startRecognize() {
try {
if (!this.h5_scan) {
//创建扫码实例
this.h5_scan = plus.barcode.create('barcode', [plus.barcode.QR], {
top: '44px',
//留出头部导航空间
left: '0',
width: '100%',
height: '50%',
position: 'static'
});
//配置扫码回调
this.h5_scan.onmarked = this.onmarked;
//将扫码实例添加到当前页面中
plus.webview.currentWebview().append(this.h5_scan);
}
//开启扫码
this.h5_scan.start();
} catch(e) {
alert("出现错误啦:\n" + e);
}
},
//扫码回调
onmarked(type, result) {
//扫码成功后扫码关闭扫码界面
this.h5_scan != null && this.h5_scan.close();
//console.log(result)
uni.showToast({
title: result,
duration: 5000
})
//跳转到上一个页面
uni.navigateBack({})
}
},
//H5扫码页面
data() {
return {
h5_scan: null,//扫码实例
}
},
onLoad() {
if (window.plus) {
this.startRecognize()
} else {
document.addEventListener('plusready', this.startRecognize)
}
},
onUnload() {
//页面卸载是关闭扫码
this.h5_scan != null && this.h5_scan.close()
},
6.页面默认全屏
- 当页面的根标签需要默认高度100%时,不同平台有不同的处理方式
- 在H5中,给 uni-page-body 这个标签设置高度,页面根标签才可以继承100%高度
/* #ifdef H5 */
uni-page-body{
height:100%;
}
/* #endif */
- 而在非H5中,需要过给最外层的page标签设定高度,页面根标签才可以继承100%高度,注意,不要给scoped属性影响
<style>
page{
height:100%;
}
</style>
7.拍照与选图
相关接口:uni.chooseImage()
说明:在打包成H5模式后,这个接口仍然能够使用,在手机浏览器和pc浏览器中,会打开文件浏览的功能,让用户选择相应的图片。而在uniapp打包的app中运行改H5网页时,会弹窗让用户选择 "拍照" "文件" "图库等功能",可以说,这是一个兼容性非常好的接口。
相关代码:
var that = this
uni.chooseImage({
count: 3, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function (res) {
console.log(res)
},
})
打包成H5后,接口调用成功后,返回值如下:
参数 | 类型 | 说明 |
---|---|---|
tempFilePaths | Array |
返回值是图片列表,纯路径(blob格式) |
tempFiles | Array |
返回值是图片列表,包括图片名称,图片大小,图片路径(blob格式) |
var reader = new FileReader()
reader.readAsDataURL(res.tempFiles[0])
var formData = new FormData()
formData.append('imgTitle',res.tempFiles[0])