背景:
最近的项目有个上传文件的功能,美工给的设计图和elementUI上传组件差不多,所以想着做起来也比较简单。没想到后面的上传进度条折磨了我很久……
(主要记录自己开发过程中遇到的问题,若文章中有地方写的不对,还望大佬友善指出)
功能需求:文件大小判断,文件类型判断,上传显示进度条。
最后完成效果大概就是这样子:
功能点:
虽然说组件官网给了很多的例子,但是我项目中封装了axios请求,采用了代理服务器解决的跨域问题,所有就没有采用组件本身action,而是选用了http-request 进行自定义上传。
这些都比较简单,先上代码(以下所有代码都在同一页面下):
template中代码
// 上传组件的配置
<div class="UploadAppSon">
<el-upload
class="upload-demo"
drag
multiple
action="https://jsonplaceholder.typicode.com/posts/"
:http-request="uploadFile"
:before-upload="beforeUpload"
>
<i class="el-icon-upload" />
<div class="el-upload__text">
将文件拖到此处,或<em>点击上传</em>
</div>
<br>
<span
style="color:#999999;"
>支持上安卓apk、苹果ipa格式文件</span>
</el-upload>
</div>
drag | 是否启用拖拽上传 |
multiple | 是否支持多选文件 |
action | 必选参数,上传的地址 |
http-request | 覆盖默认的上传行为,可以自定义上传的实现 |
before-upload | 上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。 |
上方表格为组件中用到的属性详解
methods:方法中的代码 (文件上传前的校验)
// 文件上传前的校验
beforeUpload(file) {
// 类型判断
const isAPK = [
'application/vnd.android.package-archive',
'image/png'
].includes(file.type)
// 大小判断
const is1024M = file.size / 1024 / 1024 < 1024
if (!isAPK) {
// 类型不匹配
this.$message.error('上传文件只能是 apk、ipa 格式!')
}
if (!is1024M) {
// 大小不匹配
this.$message.error('上传文件大小不能超过 1GB !')
}
// 返回 false 阻断 true 正常上传
return isAPK && is1024M
},
到这一步,文件上传前的校验就已经完成了,现在需要完成自定义上传以及进度条的展示。因为使用了自定义上传,所以覆盖掉了上传组件自带的进度条显示,点击文件后直接显示成功图标。没有了进度条,在网上找了很多资料,最终下面两个方法组合完成进度条展示:
- axios的onUploadProgress方法(
axios
本身就有提供文件上传下载的进度值方法,进度有值,本身就代表请求中。)来获取上传进度。 - 利用onProgress()方法,来实现对进度条数值的定义。
// 覆盖默认的上传行为,可以自定义上传的实现
async uploadFile(param) {
// param.file就是上传文件本身
const formData = new FormData()
formData.append('file', param.file)
formData.append('PHP_SESSION_UPLOAD_PROGRESS', 'file1')
// 发起请求
request({
method: 'post',
// 上传地址,因为我这里的request请求是自己封装过的,所以就只需要填写接口后面的地址即可
url: '/App/upfile',
data: formData,
// 重点一:complete就是处理后的上传进度数值1-100
onUploadProgress: progressEvent => {
const complete = parseInt(
((progressEvent.loaded / progressEvent.total) * 100) | 0,
10
)
// 重点二:onProgress()方法需要以上方接收的形参来调用
// 这个方法有一个参数"percent",给他进度值 complete 即可
param.onProgress({ percent: complete })
}
}).then(res => {
console.log(res)
})
},
到这里,就完成了文件上传前的验证以及展示进度条的功能。
划重点!!!!!!!!!!!!
我这里的request是封装过的axios请求,统一配置过项目基地址,并在请求拦截器中添加了请求头,携带了的token。这里能直接用request方法是因为我在上面导入了这个方法:
最后这个axios请求须根据你们的项目情况来具体配置。