前言
最近在用vue开发一个后台管理系统,搭配着Element-UI一起使用。其中一个部分用到了Element-UI中的upload组件,在用的过程中碰到了不少的小坑,官网上一些函数的用法只是在Attribute属性中做了一些简介,我觉得还不够清晰,所以想写一些我在第一次使用upload组件时候遇到的坑和小问题给大家分享一下。
坑1/:onSuccess:'uploadSuccess' onError:'uploadError'
刚看到红色文字的我,很激动,心里理所应当的就认为:触发on-success钩子的时候就代表文件上传成功,触发on-error的时候就代表着文件上传失败。于是哗哗哗就写下了下面几行代码。
uploadSuccess(){ this.$message({ message: '恭喜你,上传成功', type: 'success' }); }, uploadError(){ this.$message.error('上传失败,请重新上传'); }
嘿嘿嘿,很开心,以为这两个钩子已经完美的处理了我的问题了。在后来测试发现,无论上传成功上传失败显示的都是:恭喜你,上传生成。这时候我就发现问题来了,上传成功与失败是根据后台小哥给我返回的status来判断的(我我们这边定义好的接口),当他返回的status的值为1时就是上传成功,status的值为0的时候就是文件已经存在,status的值为-1的时候就上传失败。由于后台没有给我抛出错误,所以根本不会走到on-error这个钩子。这时候我再仔细的看官方文档发现on-success钩子的函数中function(response, file, fileList)第一个参数是response,也就是后台给我们返回的结果。于是我把代码改成下面这样子,终于完美的解决了这个问题。
uploadSuccess(res){ if(res.status==1){ this.$message({ message: '恭喜你,上传成功', type: 'success' }); }else if(res.status==0){ this.$message({ message: res.msg, type: 'warning' }); }else{ this.$message.error('上传失败,请重新上传'); } }, uploadError(){ this.$refs.upload.clearFiles(); this.$message.error('上传失败,请重新上传'); } }
坑2/异步问题
老大想让我在文件上传前,加一个弹框,让用户修改文件名字的功能。于是我就想,在before-upload这个钩子上处理就好了吧(注明:before-upload这个钩子return fasle的话,文件会停止上传的)。于是我在before-upload钩子上直接加了个弹框,代码类似下面的。
:before-upload="beforeUpload" beforeUpload(){ this.$prompt('请输入文件名', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', inputValue:this.value, }).then(({ value }) => { return true; }).catch(() => { return false; }); }
很可惜哈哈哈,这个函数是异步执行的,然后upload组件默认是自动上传的,因为没有等到return,upload组件已经自动上传完毕了。激不激动,惊不惊喜。
于是我决定把自动上传文件这个功能给关闭了。如何关闭?点击上传
通过设置:auto-upload="false"这个属性就可以关闭自动上传的功能了。
那么关闭自动上传功能以后如何手动提交?加个ref属性,然后通过this.$refs.upload.submit();就可以手动提交了。不想加个一个提交按钮的情况下,我应该在哪里提交呢?
在官方文档中可以发现有一个on-change的钩子,它是一个检测文件状态改变时的钩子,让我欣喜的是它可以检测添加文件时的状态,让我难过的是:添加文件、上传成功和上传失败时都会被调用。
但是我还是觉得这个钩子函数充满了希望,于是对它进行多次的测试,发现它的file对象中包含了文件上传的状态,于是我就检测判断是否添加完文件后的状态。添加完文件后,弹框让用户输入文件名,当用户点击确认按钮再手动触发this.$refs.upload.submit()提交上传。代码如下:changeFile(file){ if(file.status=='ready'){ this.$prompt('请输入上传后的文件名', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', inputValue:file.name }).then(({ value }) => { this.fileName.name = value; this.$refs.upload.submit(); }).catch(() => { this.$refs.upload.clearFiles(); this.$message({ type: 'info', message: '取消文件上传' }); }); } }
小tips
在官方文档中可以看到,upload组件中有2个Methods,这两个Methods是怎么调用了呢,其实上面也有涉及到。定义一个refs属性(注意后面的upload是我refs中定义的名字),然后通过this.$refs.upload.clearFiles()、this.$refs.upload.abort()即可调用。clearsFiles可以清空显示在页面上的文件列表。