问题
当el-upload中before-upload绑定的方法用async修饰后,return false失效
element-ui对ipload组件的before-upload描述:
上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。
过程演示
以下代码使用的是此处在线运行
<el-upload
class="avatar-uploader"
action="https://jsonplaceholder.typicode.com/posts/"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload">
<img v-if="imageUrl" :src="imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
script代码中
beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return isJPG && isLt2M;
}
此时,当我上传png格式文件时,没有展示图片,提示我 上传头像图片只能是 JPG 格式!
当我给方法加上async再上传png格式文件时,展示了图片,提示我 上传头像图片只能是 JPG 格式!
结论:async修饰的同步方法return false已经不能阻止文件上传
为什么
看了element-ui上传组件,before-upload里面如何使用异步后大概理清出了思路。
文中说:
...如果存在异步,就应该返回Promise...
...
如果结果是true和false,转换成promise后,promise的状态为fulfilled,结果为false,而已。那么仍然得到的是Promise.resolve方法一样。所以这时候即便为false。仍然可以执行上传操作。
于是,我做了个调整:
async beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG 格式!');
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
}
return isJPG && isLt2M ? Promise.resolve() : Promise.reject();
}
重点:return isJPG && isLt2M ? Promise.resolve() : Promise.reject();
然后就能正常阻断文件上传了。
工作保密原则,不方便上真实代码,这里简单说一下实际需求:
我在上文件时需要判断对应表单中的数据是否正确,使用的是 this.$refs[dome].validate() 进行表单自动校验,但是这是一个异步方法,只能使用async + await的方式同步进行表单验证。于是出现上面的问题:加aysnc,方法返回false失效,不加,this.$refs[dome].validate()的会调中进行return也失效,进而进入死循环。使用上面的方式后完美解决。
最后上一下代码截图: