前言
因项目上使用了uniapp,并且使用uview1.0作为ui框架,但是使用过程中发现u-upload组件的before-upload
属性有bug,特地记录下来分享给大家,希望能够帮助到大家。
操作
u-upload组件的before-upload
属性我限制了上传图片大小,但是它还是显示上传成功了,于是网上搜索解决方案,并且修改了u-upload组件的源码才彻底解决。
1、修改u-upload组件源码
...
let flag = false
// 执行before-upload钩子
if(this.beforeUpload && typeof(this.beforeUpload) === 'function') {
// 执行回调,同时传入索引和文件列表当作参数
// 在微信,支付宝等环境(H5正常),会导致父组件定义的customBack()函数体中的this变成子组件的this
// 通过bind()方法,绑定父组件的this,让this.customBack()的this为父组件的上下文
// 因为upload组件可能会被嵌套在其他组件内,比如u-form,这时this.$parent其实为u-form的this,
// 非页面的this,所以这里需要往上历遍,一直寻找到最顶端的$parent,这里用了this.$u.$parent.call(this)
// 明白意思即可,无需纠结this.$u.$parent.call(this)的细节
let beforeResponse = this.beforeUpload.bind(this.$u.$parent.call(this))(index, this.lists);
// 判断是否返回了promise
if (!!beforeResponse && typeof beforeResponse.then === 'function') {
await beforeResponse.then(res => {
// promise返回成功,不进行动作,继续上传
}).catch(err => {
flag = true
this.lists.splice(index, 1);
this.$forceUpdate();
// 进入catch回调的话,继续下一张
return this.uploadFile(index + 1);
})
// promise 或 async 返回 false,或进入 catch 回调,继续下一张;否则不进行动作,继续上传
} else if(beforeResponse === false) {
// 如果返回false,继续下一张图片的上传
return this.uploadFile(index + 1);
} else {
// 此处为返回"true"的情形,这里不写代码,就跳过此处,继续执行当前的上传逻辑
}}
// 检查上传地址
if (!this.action) {
this.showToast('请配置上传地址', true);
return;
}
// 如果在beforeUpload中被拒绝,则不往后执行
if(flag) return false
大家可以参考我的代码进行修改
2、修改before-upload
属性方法
u-upload组件:
<u-upload
ref="uUpload"
:action="upload.action"
:custom-btn="true"
:auto-upload="true"
:file-list="upload.fileList"
max-count="5"
:header= "{
'Content-Type': 'multipart/form-data',
'Authorization': `Bearer ${$store.state.vuex_token}`}"
:before-upload="beforeUpload"
@on-change='uploadImgChange'>
<view class="uploadimg" slot="addBtn">
<image class="img" :src="mediaPrefix + 'wxresource/user/upload_default.png'" mode="widthFix"></image>
</view>
</u-upload>
beforeUpload方法:
beforeUpload(index, fileList){
const file = fileList[index];
console.log('beforeUpload file',JSON.stringify(file))
return new Promise((resolve, reject) => {
// 使用uni.getImageInfo()获取图片实际尺寸
uni.getImageInfo({
src: file.url,
success: function(info) {
console.log('info.width=',info.width)
const width = info.width;
const height = info.height;
// 判断图片尺寸是否超过最大值
if (width && height) {
let f = 1
if(width>height){
f = width/height
}
if(height>width){
f = height/width
}
if(f>2){
uni.showToast({
title: `请上传长宽比为2:1范围内尺寸的图片`,
icon: 'none',
duration: 5000
});
reject('请上传长宽比为2:1范围内尺寸的图片');
}
}
resolve(file);
},
fail: function() {
uni.showToast({
title: '获取图片信息失败',
icon: 'none'
});
return reject();
}
});
});
},
这样就解决了限制图片上传问题。
总结
1、u-upload的before-upload
属性源码有bug,网友已经发现了,并且也提了PR可是官方并没有跟进
引用
before-upload 用 async 返回 false 仍执行上传
修复 before-upload 和 before-remove 使用 async 返回 false 仍往下执行的问题 #1124
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。